
#include <stdio.h>
#include <map>
#include <set>

//----------------
template<typename Key, typename Value, typename Predicate>
void filter(const std::map<Key, Value> &m, std::set<Value> &result, Predicate &p) {
   std::map<Key, Value>::const_iterator it = m.begin();
   std::map<Key, Value>::const_iterator end = m.end();

   for( ; it != end; ++it) {
      Key key = it->first;
      if(p(key))
         result.insert(it->second);
   }
}
//----------------
typedef int FamilyId;
typedef int EntityId;
struct EntitySystem;

struct Component {
};

struct Entity {
   static EntitySystem *entitySystem;
   Entity(EntityId id);
   template<typename Type> Type *getAs();
   EntityId mId;
};
EntitySystem *Entity::entitySystem = 0;

struct EntitySystem {
   EntitySystem() {
      Entity::entitySystem = this;
   }
   EntityId getNextAvailableID() {
      static EntityId counter = 0;
      return ++counter;
   }
   void registerEntity(Entity *e) {
      mEntities.insert(std::pair<EntityId, Entity*>(e->mId, e));
   }
   Entity *getEntity(EntityId id) {
      return mEntities[id];
   }
   void killEntity(EntityId id) {
      std::map<EntityId, Entity*>::iterator toKill = mEntities.find(id);
      mEntities.erase(toKill);
      //what to do with the components?
   }
   template<typename T> T *getComponent(Entity *e) {
      std::map<Entity*, Component*> &store = mComponentStore[T::familyId];
      return (T*)store[e];
   }
   template<typename T> void getEntities(std::set<Entity*> &result) {
      struct isEqual {
         isEqual(const FamilyId family_) : family(family_) {}
         bool operator()(const FamilyId val) {
            return val == family;
         }
         FamilyId family;
      };
      filter(mEntities, result, isEqual(T::familyId));
   }
   template<typename T> void addComponent(Entity *e, T* comp) {
      mComponentStore[T::familyId].insert(std::pair<Entity*, Component*>(e, comp));
   }
protected:
   std::map<EntityId, Entity*> mEntities;
   std::map<FamilyId, std::map<Entity*, Component*> > mComponentStore;
};

Entity::Entity(EntityId id) {
   mId = id;
   entitySystem->registerEntity(this);
}

template<typename Type> Type *Entity::getAs() {
   return entitySystem->getComponent<Type>(this);
}

struct Position : public Component {
   static const FamilyId familyId = 1;
   float x,y;
   float width, height;
};

void main() {
   EntitySystem system;
   Entity e(system.getNextAvailableID());   //create entity
   
   Entity *g = system.getEntity(e.mId);   //get entity
   Position *toInsert = new Position();
   system.addComponent(g, toInsert);

   Position *position = g->getAs<Position>();
   Position *pos2 = system.getComponent<Position>(g);

   //get list of entities with position-component
   std::set<Entity*> positionList;
   system.getEntities<Position>(positionList);
}
