Indulge a bit on the template wizardy
authorMarco Costalba <mcostalba@gmail.com>
Sun, 14 Aug 2011 11:36:34 +0000 (12:36 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 14 Aug 2011 12:15:58 +0000 (13:15 +0100)
Push the template pedal a bit in our "showoff" endgame code ;-)

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/endgame.cpp
src/endgame.h

index c55013f3ac141f531c3bee0192a63ee4da85eb17..0856883bf5e39a484241741f77a79ba9b2534f30 100644 (file)
@@ -93,16 +93,16 @@ namespace {
     return Position(fen, false, 0).get_material_key();
   }
 
-  typedef EndgameBase<Value> EF;
-  typedef EndgameBase<ScaleFactor> SF;
+  typedef Endgames::EMap<Value>::type EFMap;
+  typedef Endgames::EMap<ScaleFactor>::type SFMap;
 
 } // namespace
 
 
 /// Endgames member definitions
 
-template<> const Endgames::EFMap& Endgames::map<EF>() const { return maps.first; }
-template<> const Endgames::SFMap& Endgames::map<SF>() const { return maps.second; }
+template<> const EFMap& Endgames::map<Value>() const { return maps.first; }
+template<> const SFMap& Endgames::map<ScaleFactor>() const { return maps.second; }
 
 Endgames::Endgames() {
 
@@ -125,10 +125,10 @@ Endgames::Endgames() {
 
 Endgames::~Endgames() {
 
-  for (EFMap::const_iterator it = map<EF>().begin(); it != map<EF>().end(); ++it)
+  for (EFMap::const_iterator it = map<Value>().begin(); it != map<Value>().end(); ++it)
       delete it->second;
 
-  for (SFMap::const_iterator it = map<SF>().begin(); it != map<SF>().end(); ++it)
+  for (SFMap::const_iterator it = map<ScaleFactor>().begin(); it != map<ScaleFactor>().end(); ++it)
       delete it->second;
 }
 
@@ -137,23 +137,22 @@ void Endgames::add(const string& keyCode) {
 
   typedef Endgame<T, E> EG;
   typedef typename EG::Base B;
-  typedef std::map<Key, B*> M;
+  typedef typename EMap<T>::type M;
 
-  const_cast<M&>(map<B>()).insert(std::pair<Key, B*>(mat_key(keyCode), new EG(WHITE)));
-  const_cast<M&>(map<B>()).insert(std::pair<Key, B*>(mat_key(swap_colors(keyCode)), new EG(BLACK)));
+  const_cast<M&>(map<T>()).insert(std::pair<Key, B*>(mat_key(keyCode), new EG(WHITE)));
+  const_cast<M&>(map<T>()).insert(std::pair<Key, B*>(mat_key(swap_colors(keyCode)), new EG(BLACK)));
 }
 
 template<typename T>
 EndgameBase<T>* Endgames::get(Key key) const {
 
-  typedef EndgameBase<T> E;
-  typename std::map<Key, E*>::const_iterator it = map<E>().find(key);
-  return it != map<E>().end() ? it->second : NULL;
+  typename EMap<T>::type::const_iterator it = map<T>().find(key);
+  return it != map<T>().end() ? it->second : NULL;
 }
 
 // Explicit template instantiations
-template EF* Endgames::get<Value>(Key key) const;
-template SF* Endgames::get<ScaleFactor>(Key key) const;
+template EndgameBase<Value>* Endgames::get<Value>(Key key) const;
+template EndgameBase<ScaleFactor>* Endgames::get<ScaleFactor>(Key key) const;
 
 
 /// Mate with KX vs K. This function is used to evaluate positions with
index af5da0519ec8bb0bc624ea03459c9eff8dac2c79..a9634738bee0232c5c03117d62a21688a1a465cf 100644 (file)
@@ -89,12 +89,11 @@ private:
 /// and scaling base objects. Then we use polymorphism to invoke the actual
 /// endgame function calling its apply() method that is virtual.
 
-class Endgames {
+struct Endgames {
 
-  typedef std::map<Key, EndgameBase<Value>* > EFMap;
-  typedef std::map<Key, EndgameBase<ScaleFactor>* > SFMap;
+  template<typename T>
+  struct EMap { typedef std::map<Key, EndgameBase<T>*> type; };
 
-public:
   Endgames();
   ~Endgames();
   template<typename T> EndgameBase<T>* get(Key key) const;
@@ -103,10 +102,10 @@ private:
   template<typename T, EndgameType E> void add(const std::string& keyCode);
 
   // Here we store two maps, for evaluate and scaling functions...
-  std::pair<EFMap, SFMap> maps;
+  std::pair<EMap<Value>::type, EMap<ScaleFactor>::type> maps;
 
   // ...and here is the accessing template function
-  template<typename T> const std::map<Key, T*>& map() const;
+  template<typename T> const typename EMap<T>::type& map() const;
 };
 
 #endif // !defined(ENDGAME_H_INCLUDED)