From cfeaeabf2df5c46d9dcecc35600873c86ba14b41 Mon Sep 17 00:00:00 2001
From: Sam Hocevar <sam@hocevar.net>
Date: Wed, 3 Jan 2018 13:36:04 +0100
Subject: [PATCH] Get rid of lol::map because std::map is obviously superior.

---
 doc/grammar/lolfx-scanner.l           |   9 +-
 doc/samples/btphystest.h              |   3 +-
 doc/samples/meshviewer/meshviewer.cpp |  20 +-
 doc/samples/meshviewer/meshviewer.h   |   5 +-
 doc/samples/meshviewer/scenesetup.cpp |   9 +-
 doc/samples/meshviewer/scenesetup.h   |  11 +-
 src/easymesh/easymesh.h               |  30 +--
 src/easymesh/easymeshbuild.h          |  22 ++-
 src/easymesh/easymeshlua.cpp          |  13 +-
 src/easymesh/easymeshlua.h            |  11 +-
 src/easymesh/easymeshrender.h         |   4 +-
 src/gpu/shader.cpp                    |  68 ++++---
 src/image/image-private.h             |  18 +-
 src/image/image.cpp                   |  19 +-
 src/input/controller.h                |   3 +-
 src/lol/base/enum.h                   |  13 +-
 src/lol/base/map.h                    | 130 +++---------
 src/lol/gpu/shader.h                  |  21 +-
 src/lol/gpu/vertexbuffer.h            |  17 +-
 src/lol/math/geometry.h               |  15 +-
 src/lol/sys/file.h                    |   9 +-
 src/lol/sys/threadtypes.h             |  22 ++-
 src/lolimgui.h                        |   7 +-
 src/messageservice.h                  |   3 +-
 src/scene.cpp                         |  15 +-
 src/sys/threadtypes.cpp               |  18 +-
 src/t/base/enum.cpp                   |   3 +-
 src/t/base/map.cpp                    | 271 +-------------------------
 src/t/sys/thread.cpp                  |   3 +-
 29 files changed, 248 insertions(+), 544 deletions(-)

diff --git a/doc/grammar/lolfx-scanner.l b/doc/grammar/lolfx-scanner.l
index 59dacf7a..a88b2f2d 100644
--- a/doc/grammar/lolfx-scanner.l
+++ b/doc/grammar/lolfx-scanner.l
@@ -2,9 +2,9 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010-2015 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2012—2018 Sam Hocevar <sam@hocevar.net>
 //
-//  This program is free software. It comes without any warranty, to
+//  Lol Engine is free software. It comes without any warranty, to
 //  the extent permitted by applicable law. You can redistribute it
 //  and/or modify it under the terms of the Do What the Fuck You Want
 //  to Public License, Version 2, as published by the WTFPL Task Force.
@@ -21,6 +21,7 @@ using std::malloc;
 using std::realloc;
 using std::free;
 #include <iostream>
+#include <map>
 
 #include "core.h"
 #include "gpu/lolfx-compiler.h"
@@ -534,7 +535,7 @@ typedef lol::LolFxParser::token_type token_type;
     while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0')
         tmp++;
     String key(tmp2, (int)(tmp - tmp2));
-    if (m_pp_defines.has_key(key))
+    if (has_key(m_pp_defines, key))
     {
         m_pp_stack.Push(BlockIsTrue);
     }
@@ -556,7 +557,7 @@ typedef lol::LolFxParser::token_type token_type;
     while (*tmp != ' ' && *tmp != '\n' && *tmp != '\0')
         tmp++;
     String key(tmp2, (int)(tmp - tmp2));
-    if (m_pp_defines.has_key(key))
+    if (has_key(m_pp_defines, key))
     {
         m_pp_stack.Push(BlockIsFalse);
         BEGIN(PREPROCESSOR_COMMENT);
diff --git a/doc/samples/btphystest.h b/doc/samples/btphystest.h
index 0a5d0612..26ba2112 100644
--- a/doc/samples/btphystest.h
+++ b/doc/samples/btphystest.h
@@ -14,6 +14,7 @@
 #pragma once
 
 #include <string>
+#include <map>
 
 class CatShaderData : public GpuShaderData
 {
@@ -70,7 +71,7 @@ private:
             KEY_MAX
         };
     protected:
-        virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+        virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
         {
             enum_map[KEY_MOVE_FORWARD] = g_name_key_Up;
             enum_map[KEY_MOVE_BACK] = g_name_key_Down;
diff --git a/doc/samples/meshviewer/meshviewer.cpp b/doc/samples/meshviewer/meshviewer.cpp
index a39b040a..d65c1e0b 100644
--- a/doc/samples/meshviewer/meshviewer.cpp
+++ b/doc/samples/meshviewer/meshviewer.cpp
@@ -17,6 +17,7 @@
 
 #include <cfloat> /* for FLT_MAX */
 #include <string>
+#include <map>
 
 #include <lol/engine.h>
 #include <lol/lua.h>
@@ -113,14 +114,13 @@ void EasyMeshViewerObject::TickDraw(float seconds, Scene &scene)
 //EasyMeshLoadJob -------------------------------------------------------------
 bool EasyMeshLoadJob::DoWork()
 {
-    map<std::string, EasyMeshLuaObject*> meshes;
+    std::map<std::string, EasyMeshLuaObject*> meshes;
     if (m_loader.ExecLuaFile(m_path) && EasyMeshLuaLoader::GetRegisteredMeshes(meshes))
     {
-        array<std::string> keys = meshes.keys();
-        for (auto const &key : keys)
-            m_meshes << new EasyMeshViewerObject(key, meshes[key]->GetMesh());
+        for (auto const &kv : meshes)
+            m_meshes << new EasyMeshViewerObject(kv.first, kv.second->GetMesh());
     }
-    return !!m_meshes.count();
+    return m_meshes.count() > 0;
 }
 
 //-----------------------------------------------------------------------------
@@ -243,9 +243,8 @@ void MeshViewer::Stop()
 void MeshViewer::UpdateSceneSetup(bool only_destroy)
 {
     //Delete previous setups
-    array<std::string> keys = m_ssetups.keys();
-    for (auto const &key : keys)
-        delete m_ssetups[key];
+    for (auto &key : m_ssetups)
+        delete key.second;
     m_ssetups.empty();
     if (m_ssetup_file_status)
     {
@@ -261,9 +260,8 @@ void MeshViewer::UpdateSceneSetup(bool only_destroy)
         if (m_ssetup_loader.GetLoadedSetups(m_ssetups))
         {
             m_ssetup_file_status = m_file_check->RegisterFile(m_ssetup_file_name);
-            array<std::string> keys = m_ssetups.keys();
-            if (!m_ssetup_name.length() || !keys.find(m_ssetup_name))
-                m_ssetup_name = keys[0];
+            if (!m_ssetup_name.length() || !has_key(m_ssetups, m_ssetup_name))
+                m_ssetup_name = m_ssetups.begin()->first;
         }
     }
 }
diff --git a/doc/samples/meshviewer/meshviewer.h b/doc/samples/meshviewer/meshviewer.h
index 9d7f55cb..1406c524 100644
--- a/doc/samples/meshviewer/meshviewer.h
+++ b/doc/samples/meshviewer/meshviewer.h
@@ -14,6 +14,7 @@
 #pragma once
 
 #include <string>
+#include <map>
 
 namespace lol
 {
@@ -93,7 +94,7 @@ struct MeshViewerKeyInputBase : public StructSafeEnum
         MAX = MSE_END,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[Exit] = g_name_key_Escape;
 
@@ -271,7 +272,7 @@ private:
     FileUpdateStatus *m_ssetup_file_status = nullptr;
     std::string m_ssetup_file_name;
     std::string m_ssetup_name;
-    map<std::string, SceneSetup*> m_ssetups;
+    std::map<std::string, SceneSetup*> m_ssetups;
 
     //File data
     std::string             m_file_name;
diff --git a/doc/samples/meshviewer/scenesetup.cpp b/doc/samples/meshviewer/scenesetup.cpp
index 23eb36ff..05924f6b 100644
--- a/doc/samples/meshviewer/scenesetup.cpp
+++ b/doc/samples/meshviewer/scenesetup.cpp
@@ -19,6 +19,7 @@
 #include <lol/lua.h>
 
 #include <string>
+#include <map>
 
 #include "scenesetup.h"
 
@@ -264,7 +265,7 @@ const LuaObjectLibrary* SceneSetupLuaObject::GetLib()
 }
 
 //-----------------------------------------------------------------------------
-map<std::string, SceneSetup*> SceneSetupLuaLoader::m_setups;
+std::map<std::string, SceneSetup*> SceneSetupLuaLoader::m_setups;
 SceneSetupLuaLoader::SceneSetupLuaLoader() : LuaLoader()
 {
     lua_State* l = GetLuaState();
@@ -296,14 +297,14 @@ void SceneSetupLuaLoader::RegisterSetup(SceneSetup* setup)
 }
 
 //-----------------------------------------------------------------------------
-bool SceneSetupLuaLoader::GetRegisteredSetups(map<std::string, SceneSetup*>& setups)
+bool SceneSetupLuaLoader::GetRegisteredSetups(std::map<std::string, SceneSetup*>& setups)
 {
     setups = m_setups;
-    return !!m_setups.count();
+    return m_setups.size() > 0;
 }
 
 //-----------------------------------------------------------------------------
-bool SceneSetupLuaLoader::GetLoadedSetups(map<std::string, SceneSetup*>& setups)
+bool SceneSetupLuaLoader::GetLoadedSetups(std::map<std::string, SceneSetup*>& setups)
 {
     return GetRegisteredSetups(setups);
 }
diff --git a/doc/samples/meshviewer/scenesetup.h b/doc/samples/meshviewer/scenesetup.h
index 1b99f69b..23c36c25 100644
--- a/doc/samples/meshviewer/scenesetup.h
+++ b/doc/samples/meshviewer/scenesetup.h
@@ -19,6 +19,7 @@
 //
 
 #include <string>
+#include <map>
 
 namespace lol
 {
@@ -61,7 +62,7 @@ public:
             Max
         };
     protected:
-        virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+        virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
         {
             enum_map[Gizmo] = "Gizmo";
             enum_map[Light] = "Light";
@@ -88,7 +89,7 @@ protected:
             Max
         };
     protected:
-        virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+        virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
         {
             enum_map[AddLight] = "AddLight";
             enum_map[SetupScene] = "SetupScene";
@@ -163,12 +164,12 @@ public:
     //-------------------------------------------------------------------------
 protected:
     static void RegisterSetup(SceneSetup* setup);
-    static bool GetRegisteredSetups(map<std::string, SceneSetup*>& setups);
+    static bool GetRegisteredSetups(std::map<std::string, SceneSetup*>& setups);
 public:
-    bool GetLoadedSetups(map<std::string, SceneSetup*>& setups);
+    bool GetLoadedSetups(std::map<std::string, SceneSetup*>& setups);
 
 private:
-    static map<std::string, SceneSetup*> m_setups;
+    static std::map<std::string, SceneSetup*> m_setups;
 };
 
 /*
diff --git a/src/easymesh/easymesh.h b/src/easymesh/easymesh.h
index 31198e37..aa429d5a 100644
--- a/src/easymesh/easymesh.h
+++ b/src/easymesh/easymesh.h
@@ -1,14 +1,15 @@
 //
-// EasyMesh: A class about generating 3D mesh without using the hands
-//           Mesh can be generated using C++ or lua code
+//  Lol Engine
+//
+//  Copyright © 2009—2013 Cédric Lecacheur <jordx@free.fr>
+//            © 2009—2013 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
+//            © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //
-// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
-//            (c) 2009-2013 Cédric Lecacheur <jordx@free.fr>
-//            (c) 2009-2013 Benjamin "Touky" Huet <huet.benjamin@gmail.com>
-//   This program is free software; you can redistribute it and/or
-//   modify it under the terms of the Do What The Fuck You Want To
-//   Public License, Version 2, as published by Sam Hocevar. See
-//   http://www.wtfpl.net/ for more details.
+//  Lol Engine is free software. It comes without any warranty, to
+//  the extent permitted by applicable law. You can redistribute it
+//  and/or modify it under the terms of the Do What the Fuck You Want
+//  to Public License, Version 2, as published by the WTFPL Task Force.
+//  See http://www.wtfpl.net/ for more details.
 //
 
 #pragma once
@@ -17,6 +18,13 @@
 #include "easymeshrender.h"
 #include "easymeshbuild.h"
 
+#include <map>
+
+//
+// EasyMesh: A class about generating 3D mesh without using the hands
+//           Mesh can be generated using C++ or lua code
+//
+
 namespace lol
 {
 
@@ -33,7 +41,7 @@ struct CSGUsageBase : public StructSafeEnum
         Xor
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Union] = "Union";
         enum_map[Substract] = "Substract";
@@ -57,7 +65,7 @@ struct MeshTransformBase : public StructSafeEnum
         Shear
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Taper] = "Taper";
         enum_map[Twist] = "Twist";
diff --git a/src/easymesh/easymeshbuild.h b/src/easymesh/easymeshbuild.h
index e4f7c458..b3d66f11 100644
--- a/src/easymesh/easymeshbuild.h
+++ b/src/easymesh/easymeshbuild.h
@@ -1,9 +1,9 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2009—2013 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
-//            © 2010—2017 Sam Hocevar <sam@hocevar.net>
-//            © 2009—2013 Cédric Lecacheur <jordx@free.fr>
+//  Copyright © 2009—2013 Cédric Lecacheur <jordx@free.fr>
+//            © 2009—2013 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
+//            © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //
 //  Lol Engine is free software. It comes without any warranty, to
 //  the extent permitted by applicable law. You can redistribute it
@@ -14,6 +14,8 @@
 
 #pragma once
 
+#include <map>
+
 // Vertex building operations
 
 namespace lol
@@ -36,7 +38,7 @@ struct MeshBuildOperationBase : public StructSafeEnum
         All = 0xffff,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[ScaleWinding] = "ScaleWinding";
         enum_map[CommandRecording] = "CommandRecording";
@@ -97,7 +99,7 @@ struct EasyMeshCmdTypeBase : public StructSafeEnum
         AppendCog,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[MeshCsg] = "MeshCsg";
         enum_map[LoopStart] = "LoopStart";
@@ -158,7 +160,7 @@ struct MeshTypeBase : public StructSafeEnum
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Triangle] = "Triangle";
         enum_map[Quad] = "Quad";
@@ -198,7 +200,7 @@ struct TexCoordBuildTypeBase : public StructSafeEnum
         Max
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[TriangleDefault] = "TriangleDefault";
         enum_map[QuadDefault] = "QuadDefault";
@@ -233,7 +235,7 @@ struct MeshFaceTypeBase : public StructSafeEnum
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[BoxFront] = "BoxFront";
         enum_map[QuadDefault] = "QuadDefault";
@@ -259,7 +261,7 @@ struct TexCoordPosBase : public StructSafeEnum
         TR  // Top Right
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[BL] = "BL";
         enum_map[BR] = "BR";
@@ -510,7 +512,7 @@ struct VDictTypeBase : public StructSafeEnum
         Master = -1,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[DoesNotExist] = "DoesNotExist";
         enum_map[Alone] = "Alone";
diff --git a/src/easymesh/easymeshlua.cpp b/src/easymesh/easymeshlua.cpp
index 6b313c36..30fdf7fe 100644
--- a/src/easymesh/easymeshlua.cpp
+++ b/src/easymesh/easymeshlua.cpp
@@ -1,5 +1,5 @@
 //
-//  Lol Engine — EasyMesh Lua loader
+//  Lol Engine
 //
 //  Copyright © 2009—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
 //            © 2017—2018 Sam Hocevar <sam@hocevar.net>
@@ -20,9 +20,14 @@
 
 #include <cstdio>
 #include <string>
+#include <map>
 
 #include "loldebug.h"
 
+//
+//  EasyMesh Lua loader
+//
+
 using namespace lol;
 
 //-----------------------------------------------------------------------------
@@ -55,17 +60,17 @@ array<EasyMeshLuaObject*>& EasyMeshLuaLoader::GetInstances()
 }
 
 //-----------------------------------------------------------------------------
-map<std::string, EasyMeshLuaObject*> EasyMeshLuaLoader::m_meshes;
+std::map<std::string, EasyMeshLuaObject*> EasyMeshLuaLoader::m_meshes;
 void EasyMeshLuaLoader::RegisterMesh(EasyMeshLuaObject* mesh, std::string const& name)
 {
     m_meshes[name] = mesh;
 }
 
 //-----------------------------------------------------------------------------
-bool EasyMeshLuaLoader::GetRegisteredMeshes(map<std::string, EasyMeshLuaObject*>& meshes)
+bool EasyMeshLuaLoader::GetRegisteredMeshes(std::map<std::string, EasyMeshLuaObject*>& meshes)
 {
     meshes = m_meshes;
-    return m_meshes.count() > 0;
+    return m_meshes.size() > 0;
 }
 
 //-----------------------------------------------------------------------------
diff --git a/src/easymesh/easymeshlua.h b/src/easymesh/easymeshlua.h
index 35c051c6..1a5e3dee 100644
--- a/src/easymesh/easymeshlua.h
+++ b/src/easymesh/easymeshlua.h
@@ -1,5 +1,5 @@
 //
-//  Lol Engine — EasyMesh Lua loader
+//  Lol Engine
 //
 //  Copyright © 2009—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
 //            © 2017—2018 Sam Hocevar <sam@hocevar.net>
@@ -14,6 +14,11 @@
 #pragma once
 
 #include <string>
+#include <map>
+
+//
+//  EasyMesh Lua loader
+//
 
 namespace lol
 {
@@ -142,10 +147,10 @@ public:
 protected:
     static void RegisterMesh(EasyMeshLuaObject* mesh, std::string const& name);
 public:
-    static bool GetRegisteredMeshes(map<std::string, EasyMeshLuaObject*>& meshes);
+    static bool GetRegisteredMeshes(std::map<std::string, EasyMeshLuaObject*>& meshes);
 
 private:
-    static map<std::string, EasyMeshLuaObject*> m_meshes;
+    static std::map<std::string, EasyMeshLuaObject*> m_meshes;
 };
 
 } /* namespace lol */
diff --git a/src/easymesh/easymeshrender.h b/src/easymesh/easymeshrender.h
index 0454847b..97585e4d 100644
--- a/src/easymesh/easymeshrender.h
+++ b/src/easymesh/easymeshrender.h
@@ -14,6 +14,8 @@
 
 #pragma once
 
+#include <map>
+
 namespace lol
 {
 
@@ -29,7 +31,7 @@ struct MeshRenderBase : public StructSafeEnum
         IgnoreRender,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[NeedData] = "NeedData";
         enum_map[NeedConvert] = "NeedConvert";
diff --git a/src/gpu/shader.cpp b/src/gpu/shader.cpp
index d31a6c90..137242e6 100644
--- a/src/gpu/shader.cpp
+++ b/src/gpu/shader.cpp
@@ -13,6 +13,7 @@
 #include <lol/engine-internal.h>
 
 #include <string>
+#include <map>
 #include <cstring>
 #include <cstdio>
 
@@ -81,8 +82,8 @@ private:
 
     GLuint prog_id, vert_id, frag_id;
     // Benlitz: using a simple array could be faster since there is never more than a few attribute locations to store
-    map<uint64_t, GLint> attrib_locations;
-    map<uint64_t, bool> attrib_errors;
+    std::map<uint64_t, GLint> attrib_locations;
+    std::map<uint64_t, bool> attrib_errors;
     uint32_t vert_crc, frag_crc;
 
     /* Shader patcher */
@@ -110,7 +111,7 @@ struct lolfx_parser
 {
 public:
     std::string m_section;
-    map<std::string, std::string> m_programs;
+    std::map<std::string, std::string> m_programs;
 
 private:
     // title <- '[' (!']')+ ']' .{eol}
@@ -192,10 +193,10 @@ Shader *Shader::Create(std::string const &name, std::string const &code)
 {
     lolfx_parser p(code);
 
-    ASSERT(p.m_programs.has_key("vert.glsl"),
+    ASSERT(has_key(p.m_programs, "vert.glsl"),
            "no vertex shader in %s", name.c_str());
 
-    ASSERT(p.m_programs.has_key("frag.glsl"),
+    ASSERT(has_key(p.m_programs, "frag.glsl"),
            "no fragment shader in %s", name.c_str());
 
     std::string vert = p.m_programs["vert.glsl"];
@@ -355,7 +356,7 @@ Shader::Shader(std::string const &name,
             flags |= (uint64_t)(uint16_t)index;
             // TODO: this is here just in case. Remove this once everything has been correctly tested
 #if _DEBUG
-            if (data->attrib_locations.has_key(flags))
+            if (has_key(data->attrib_locations, flags))
             {
                 msg::error("error while parsing attribute semantics in %s\n",
                            attr_name.c_str());
@@ -370,7 +371,7 @@ Shader::Shader(std::string const &name,
 
 int Shader::GetAttribCount() const
 {
-    return data->attrib_locations.count();
+    return data->attrib_locations.size();
 }
 
 ShaderAttrib Shader::GetAttribLocation(VertexUsage usage, int index) const
@@ -381,10 +382,10 @@ ShaderAttrib Shader::GetAttribLocation(VertexUsage usage, int index) const
 
     GLint l = -1;
 
-    if (!data->attrib_locations.try_get(ret.m_flags, l))
+    if (!try_get(data->attrib_locations, ret.m_flags, l))
     {
         /* Only spit an error once, we don’t need to flood the console. */
-        if (!data->attrib_errors.has_key(ret.m_flags))
+        if (!has_key(data->attrib_errors, ret.m_flags))
         {
             msg::error("attribute %s not found in shader %s\n",
                        usage.tostring().c_str(), data->m_name.c_str());
@@ -833,34 +834,32 @@ void ShaderBlock::AddVar(ShaderVar const& var)
     ShaderVariable qualifier = var.GetQualifier();
     std::string type = var.GetType();
     std::string name = Shader::GetVariablePrefix(qualifier) + var.m_name;
-    ASSERT(!m_parameters[qualifier.ToScalar()].has_key(name));
+    ASSERT(!has_key(m_parameters[qualifier.ToScalar()], name));
     m_parameters[qualifier.ToScalar()][name] = type;
 }
 
 //----
-void ShaderBlock::AddCallParameters(map<std::string, std::string> const& variables, std::string& result)
+void ShaderBlock::AddCallParameters(std::map<std::string, std::string> const& variables, std::string& result)
 {
-    array<std::string> keys = variables.keys();
-    for (auto const &key : keys)
+    for (auto const &key : variables)
     {
         if (result.length() > 0)
             result += ", ";
-        result += key;
+        result += key.first;
     }
 }
 
 //----
-void ShaderBlock::AddDefinitionParameters(const ShaderVariable type, const ShaderProgram program, map<std::string, std::string>& variables, std::string& result)
+void ShaderBlock::AddDefinitionParameters(const ShaderVariable type, const ShaderProgram program, std::map<std::string, std::string>& variables, std::string& result)
 {
-    array<std::string> keys = variables.keys();
-    for (auto const &key : keys)
+    for (auto const &key : variables)
     {
         if (result.length() > 0)
             result += ", ";
         result += Shader::GetFunctionQualifier(type, program) + " ";
-        result += variables[key];
+        result += key.second;
         result += " ";
-        result += key;
+        result += key.first;
     }
 }
 
@@ -868,7 +867,7 @@ void ShaderBlock::AddDefinitionParameters(const ShaderVariable type, const Shade
 void ShaderBlock::Build(const ShaderProgram program, std::string& call, std::string& function)
 {
     ASSERT(m_name.length());
-    ASSERT(m_parameters[ShaderVariable::InOut].count());
+    ASSERT(m_parameters[ShaderVariable::InOut].size());
 
     //Build call in main
     std::string call_name = std::string("Call_") + m_name;
@@ -962,21 +961,20 @@ std::string ShaderBuilder::AddSlotOutVariableLocal(const ShaderProgram program)
 }
 
 //----
-void ShaderBuilder::MergeParameters(map<std::string, std::string>& variables, map<std::string, std::string>& merged)
+void ShaderBuilder::MergeParameters(std::map<std::string, std::string>& variables, std::map<std::string, std::string>& merged)
 {
-    array<std::string> keys = variables.keys();
-    for (auto const &key : keys)
+    for (auto const &key : variables)
     {
-        bool has_key = merged.has_key(key);
+        bool has_param = has_key(merged, key.first);
 
         //Key exists, check the type to make sure it's the same
-        ASSERT(!has_key || (has_key && merged[key] == variables[key]),
-            "has_key=%d, key=%s merged[key]=%s, variables[key]=%s\n",
-            (int)has_key, key.c_str(), merged[key].c_str(), variables[key].c_str());
+        ASSERT(!has_param || (has_param && merged[key.first] == variables[key.first]),
+            "has_param=%d, key=%s merged[key]=%s, variables[key]=%s\n",
+            (int)has_param, key.first.c_str(), merged[key.first].c_str(), key.second.c_str());
 
         //does not exist, had it
-        if (!has_key)
-            merged[key] = variables[key];
+        if (!has_param)
+            merged[key.first] = key.second;
     }
 }
 
@@ -1011,11 +1009,11 @@ void ShaderBuilder::Build(std::string& code)
         //Added shader variables
         for (int var = 0; var < ShaderVariable::InOut; var++)
         {
-            array<std::string> keys = m_parameters[prog][var].keys();
-            if (keys.count())
+            array<std::string> all_keys = keys(m_parameters[prog][var]);
+            if (all_keys.count())
             {
                 code += std::string("//- ") + Shader::GetVariableQualifier((ShaderVariable)var) + " ----" + g_ret;
-                for (auto const &key : keys)
+                for (auto const &key : all_keys)
                 {
                     code += Shader::GetVariableQualifier((ShaderVariable)var) + " ";
                     code += m_parameters[prog][var][key] + " " + key + ";" + g_ret;
@@ -1049,10 +1047,10 @@ void ShaderBuilder::Build(std::string& code)
 
         //Add local variables
         int var = ShaderVariable::InOut;
-        array<std::string> keys = m_parameters[prog][var].keys();
-        for (auto const &key : keys)
+        array<std::string> all_keys = keys(m_parameters[prog][var]);
+        for (auto const &key : all_keys)
         {
-            if (keys.count())
+            if (all_keys.count())
             {
                 code += g_tab + m_parameters[prog][var][key] + " " + key + ";" + g_ret;
             }
diff --git a/src/image/image-private.h b/src/image/image-private.h
index 221f3e66..1ca715b0 100644
--- a/src/image/image-private.h
+++ b/src/image/image-private.h
@@ -1,15 +1,19 @@
 //
-// Lol Engine
+//  Lol Engine
 //
-// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net>
-//   This program is free software; you can redistribute it and/or
-//   modify it under the terms of the Do What The Fuck You Want To
-//   Public License, Version 2, as published by Sam Hocevar. See
-//   http://www.wtfpl.net/ for more details.
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
+//
+//  Lol Engine is free software. It comes without any warranty, to
+//  the extent permitted by applicable law. You can redistribute it
+//  and/or modify it under the terms of the Do What the Fuck You Want
+//  to Public License, Version 2, as published by the WTFPL Task Force.
+//  See http://www.wtfpl.net/ for more details.
 //
 
 #pragma once
 
+#include <map>
+
 //
 // The ImageCodecData class
 // ------------------------
@@ -61,7 +65,7 @@ public:
     WrapMode m_wrap_x, m_wrap_y;
 
     /* A map of the various available bitplanes */
-    map<int, PixelDataBase *> m_pixels;
+    std::map<int, PixelDataBase *> m_pixels;
     /* The last bitplane being accessed for writing */
     PixelFormat m_format;
 };
diff --git a/src/image/image.cpp b/src/image/image.cpp
index 7b283df5..69d013bc 100644
--- a/src/image/image.cpp
+++ b/src/image/image.cpp
@@ -1,7 +1,7 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //
 //  Lol Engine is free software. It comes without any warranty, to
 //  the extent permitted by applicable law. You can redistribute it
@@ -56,8 +56,8 @@ image & image::operator =(image other)
 
 image::~image()
 {
-    for (int k : m_data->m_pixels.keys())
-        delete m_data->m_pixels[k];
+    for (auto &kv : m_data->m_pixels)
+        delete kv.second;
 
     delete m_data;
 }
@@ -129,12 +129,9 @@ void image::resize(ivec2 size)
 
     if (m_data->m_size != size)
     {
-        for (int k : m_data->m_pixels.keys())
-        {
-            delete m_data->m_pixels[k];
-            m_data->m_pixels[k] = nullptr;
-        }
-
+        for (auto &kv : m_data->m_pixels)
+            delete kv.second;
+        m_data->m_pixels.empty();
         m_data->m_format = PixelFormat::Unknown;
     }
 
@@ -177,7 +174,7 @@ void *image::lock2d_helper(PixelFormat T)
 template<typename T>
 void image::unlock2d(array2d<T> const &array)
 {
-    ASSERT(m_data->m_pixels.has_key((int)m_data->m_format));
+    ASSERT(has_key(m_data->m_pixels, (int)m_data->m_format));
     ASSERT(array.data() == m_data->m_pixels[(int)m_data->m_format]->data());
 }
 
@@ -204,7 +201,7 @@ void *image::lock()
 
 void image::unlock(void const *pixels)
 {
-    ASSERT(m_data->m_pixels.has_key((int)m_data->m_format));
+    ASSERT(has_key(m_data->m_pixels, (int)m_data->m_format));
     ASSERT(pixels == m_data->m_pixels[(int)m_data->m_format]->data());
 }
 
diff --git a/src/input/controller.h b/src/input/controller.h
index fe0b1ee4..ecf3ddf3 100644
--- a/src/input/controller.h
+++ b/src/input/controller.h
@@ -14,6 +14,7 @@
 #pragma once
 
 #include <string>
+#include <map>
 
 namespace lol
 {
@@ -331,7 +332,7 @@ public:
             MAX,
         };
     protected:
-        virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map) { UNUSED(enum_map); return true; }
+        virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map) { UNUSED(enum_map); return true; }
     };
     typedef SafeEnum<InputTypeBase> InputType;
 
diff --git a/src/lol/base/enum.h b/src/lol/base/enum.h
index 485995bc..8a10d5e5 100644
--- a/src/lol/base/enum.h
+++ b/src/lol/base/enum.h
@@ -13,9 +13,8 @@
 
 #pragma once
 
-#include <lol/base/map.h>
-
 #include <string>
+#include <map>
 
 namespace lol
 {
@@ -27,7 +26,7 @@ namespace lol
 //    {
 //    };
 //protected:
-//    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+//    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
 //    {
 //        enum_map[] = "";
 //        return true;
@@ -40,7 +39,7 @@ struct StructSafeEnum
 {
 protected:
     /* Convert to string stuff */
-    virtual bool BuildEnumMap(map<int64_t, std::string>&) { return false; }
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>&) { return false; }
 };
 //-----------------------------------------------------------------------------
 template<typename BASE, typename T = typename BASE::Type>
@@ -63,13 +62,13 @@ public:
     {
         /* FIXME: we all know this isn’t thread safe. But is it really
         * a big deal? */
-        static map<int64_t, std::string> enum_map;
+        static std::map<int64_t, std::string> enum_map;
         static bool ready = false;
 
         if (ready || this->BuildEnumMap(enum_map))
         {
             ready = true;
-            if (enum_map.has_key((int64_t)m_value))
+            if (has_key(enum_map, (int64_t)m_value))
                 return enum_map[(int64_t)m_value];
         }
         return "<invalid enum>";
@@ -114,7 +113,7 @@ struct DisplayFlagBase : public StructSafeEnum
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[On] = "On";
         enum_map[Off] = "Off";
diff --git a/src/lol/base/map.h b/src/lol/base/map.h
index 65e605b3..986bfca9 100644
--- a/src/lol/base/map.h
+++ b/src/lol/base/map.h
@@ -1,8 +1,8 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010-2015 Sam Hocevar <sam@hocevar.net>
-//            © 2013-2015 Guillaume Bittoun <guillaume.bittoun@gmail.com>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
+//            © 2013—2015 Guillaume Bittoun <guillaume.bittoun@gmail.com>
 //
 //  Lol Engine is free software. It comes without any warranty, to
 //  the extent permitted by applicable law. You can redistribute it
@@ -14,116 +14,42 @@
 #pragma once
 
 //
-// The map class
-// -------------
-// A very simple map class.
+// Simple map utilities
+// --------------------
 //
 
-#include <lol/base/avl_tree.h>
-#include <lol/base/hash.h>
+#include <lol/base/array.h>
+
+#include <map>
 
 namespace lol
 {
 
-template<typename K, typename V> class map : protected hash<K>
+template <typename T>
+static inline bool has_key(T const &m, typename T::key_type const &key)
 {
-public:
-    /* If E is different from K, hash<K> must implement operator()(E const&)
-     * and an equality operator between K and E must exist in order to use
-     * this method. */
-
-    /* I choose to make this inline because passing the key by reference
-     * is usually suboptimal. */
-    template <typename E>
-    inline V const& operator[] (E const &key) const
-    {
-        /* Look for the hash in our table and return the value. */
-        V *value_ptr = nullptr;
-        bool found = m_tree.try_get(key, value_ptr);
-
-        ASSERT(found, "trying to read a nonexistent key in map");
-
-        return *value_ptr;
-    }
-
-    template <typename E>
-    inline V & operator[] (E const &key)
-    {
-        /* Look for the hash in our table and return the value if found. */
-        K typed_key(key);
-        V *value_ptr = nullptr;
-
-        bool found = m_tree.try_get(key, value_ptr);
-        if (!found)
-        {
-            /* If not found, insert a new value. */
-            m_tree.insert(typed_key, V());
-            found = m_tree.try_get(key, value_ptr);
-        }
-
-        /* This may happen if the key operator < does not behave as
-         * a comparator (i.e. doesn’t enforce a<b => !b<a) */
-        ASSERT(found, "inserted key can’t be retrieved");
-
-        return *value_ptr;
-    }
-
-    template <typename E>
-    inline void remove(E const &key)
-    {
-        K typed_key(key);
-        m_tree.erase(typed_key);
-    }
-
-    template <typename E>
-    inline bool has_key(E const &key)
-    {
-        K typed_key(key);
-        return m_tree.exists(typed_key);
-    }
-
-    template <typename E>
-    inline bool try_get(E const &key, V& value)
-    {
-        K typed_key(key);
-        V *value_ptr;
-        if (m_tree.try_get(typed_key, value_ptr))
-        {
-            value = *value_ptr;
-            return true;
-        }
+    return m.count(key) > 0;
+}
 
+template <typename T>
+static inline bool try_get(T const &m, typename T::key_type const &key,
+                           typename T::mapped_type &val)
+{
+    auto const &kv = m.find(key);
+    if (kv == m.end())
         return false;
-    }
-
-    array<K> keys() const
-    {
-        array<K> ret;
-
-        for (auto iterator : m_tree)
-            ret.push(iterator.key);
-
-        return ret;
-    }
+    val = kv->second;
+    return true;
+}
 
-    inline int count() const
-    {
-        return m_tree.count();
-    }
-
-    inline ptrdiff_t count_s() const
-    {
-        return m_tree.count_s();
-    }
-
-    inline void empty()
-    {
-        m_tree.clear();
-    }
-
-private:
-    avl_tree<K, V> m_tree;
-};
+template <typename T>
+static inline array<typename T::key_type> keys(T const &m)
+{
+    array<typename T::key_type> ret;
+    for (auto const &it : m)
+        ret << it.first;
+    return ret;
+}
 
 } /* namespace lol */
 
diff --git a/src/lol/gpu/shader.h b/src/lol/gpu/shader.h
index 87f830c6..67e58585 100644
--- a/src/lol/gpu/shader.h
+++ b/src/lol/gpu/shader.h
@@ -17,8 +17,9 @@
 // ----------------
 //
 
-#include <cstdint>
 #include <string>
+#include <map>
+#include <cstdint>
 
 #include "engine/entity.h"
 
@@ -60,7 +61,7 @@ struct VertexUsageBase : public StructSafeEnum
     };
 
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[Position] = "Position";
         enum_map[BlendWeight] = "BlendWeight";
@@ -102,7 +103,7 @@ struct ShaderVariableBase
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[Attribute] = "Attribute";
         enum_map[Uniform] = "Uniform";
@@ -126,7 +127,7 @@ struct ShaderProgramBase
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[Geometry] = "Geometry";
         enum_map[Vertex] = "Vertex";
@@ -201,7 +202,7 @@ struct ShaderVariableTypeBase
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[Bool] = "bool";
         enum_map[Int] = "int"; enum_map[UInt] = "uint";
@@ -406,7 +407,7 @@ protected:
     //--------------------------
 
     //Main shader parameters
-    map<std::string, std::string> m_parameters[ShaderVariable::MAX];
+    std::map<std::string, std::string> m_parameters[ShaderVariable::MAX];
 
     //Actual code
     std::string m_code_main;
@@ -430,8 +431,8 @@ public:
     }
 
 protected:
-    void AddCallParameters(map<std::string, std::string> const& variables, std::string& result);
-    void AddDefinitionParameters(const ShaderVariable variable, const ShaderProgram program, map<std::string, std::string>& variables, std::string& result);
+    void AddCallParameters(std::map<std::string, std::string> const& variables, std::string& result);
+    void AddDefinitionParameters(const ShaderVariable variable, const ShaderProgram program, std::map<std::string, std::string>& variables, std::string& result);
     void Build(const ShaderProgram program, std::string& call, std::string& function);
 };
 
@@ -447,7 +448,7 @@ protected:
     array<ShaderBlock*> m_blocks[ShaderProgram::MAX];
 
     //Final shader parameters
-    map<std::string, std::string> m_parameters[ShaderProgram::MAX][ShaderVariable::MAX];
+    std::map<std::string, std::string> m_parameters[ShaderProgram::MAX][ShaderVariable::MAX];
 
 public:
     ShaderBuilder(std::string const& name, std::string const& version);
@@ -460,7 +461,7 @@ public:
 
 protected:
     std::string AddSlotOutVariableLocal(const ShaderProgram program);
-    void MergeParameters(map<std::string, std::string>& variables, map<std::string, std::string>& merged);
+    void MergeParameters(std::map<std::string, std::string>& variables, std::map<std::string, std::string>& merged);
 
 public:
     void Build(std::string& code);
diff --git a/src/lol/gpu/vertexbuffer.h b/src/lol/gpu/vertexbuffer.h
index 88e94900..cde2e077 100644
--- a/src/lol/gpu/vertexbuffer.h
+++ b/src/lol/gpu/vertexbuffer.h
@@ -1,11 +1,13 @@
 //
-// Lol Engine
+//  Lol Engine
 //
-// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
-//   This program is free software; you can redistribute it and/or
-//   modify it under the terms of the Do What The Fuck You Want To
-//   Public License, Version 2, as published by Sam Hocevar. See
-//   http://www.wtfpl.net/ for more details.
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
+//
+//  Lol Engine is free software. It comes without any warranty, to
+//  the extent permitted by applicable law. You can redistribute it
+//  and/or modify it under the terms of the Do What the Fuck You Want
+//  to Public License, Version 2, as published by the WTFPL Task Force.
+//  See http://www.wtfpl.net/ for more details.
 //
 
 #pragma once
@@ -16,6 +18,7 @@
 //
 
 #include <cstring>
+#include <map>
 
 namespace lol
 {
@@ -51,7 +54,7 @@ struct MeshPrimitiveBase : public StructSafeEnum
         Lines,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Triangles]      = "Triangles";
         enum_map[TriangleStrips] = "TriangleStrips";
diff --git a/src/lol/math/geometry.h b/src/lol/math/geometry.h
index ca78af48..99b72ff9 100644
--- a/src/lol/math/geometry.h
+++ b/src/lol/math/geometry.h
@@ -1,7 +1,7 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //            © 2010—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
 //
 //  Lol Engine is free software. It comes without any warranty, to
@@ -20,10 +20,11 @@
 
 #include <lol/base/enum.h>
 
+#include <algorithm>
+#include <map>
 #include <cmath>
 #include <cstdio>
-#include <algorithm>
-#include <stdint.h>
+#include <cstdint>
 
 namespace lol
 {
@@ -36,7 +37,7 @@ struct AxisBase : public StructSafeEnum
         X = 0, Y, Z, MAX, XY = 2, XYZ = 3,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[X]   = "X";
         enum_map[Y]   = "Y";
@@ -57,7 +58,7 @@ struct DirectionBase : public StructSafeEnum
         Up = 0, Down, Left, Right, MAX,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Up]    = "Up";
         enum_map[Down]  = "Down";
@@ -259,7 +260,7 @@ struct RayIntersectBase : public StructSafeEnum
     };
     //LOL_DECLARE_ENUM_METHODS(RayIntersectBase)
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Nothing] = "Nothing";
         enum_map[All] = "All";
@@ -324,7 +325,7 @@ struct PlaneIntersectionBase : public StructSafeEnum
         Back, Front, Plane,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Back]  = "Back";
         enum_map[Front] = "Front";
diff --git a/src/lol/sys/file.h b/src/lol/sys/file.h
index 4800eb66..bbb51cfc 100644
--- a/src/lol/sys/file.h
+++ b/src/lol/sys/file.h
@@ -1,7 +1,7 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //
 //  Lol Engine is free software. It comes without any warranty, to
 //  the extent permitted by applicable law. You can redistribute it
@@ -17,7 +17,8 @@
 // -----------------------
 //
 
-#include <stdint.h>
+#include <map>
+#include <cstdint>
 
 namespace lol
 {
@@ -31,7 +32,7 @@ struct FileAccessBase : public StructSafeEnum
         Write
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[Read]  = "Read";
         enum_map[Write] = "Write";
@@ -52,7 +53,7 @@ struct StreamTypeBase : public StructSafeEnum
         FileBinary
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[StdIn]      = "StdIn";
         enum_map[StdOut]     = "StdOut";
diff --git a/src/lol/sys/threadtypes.h b/src/lol/sys/threadtypes.h
index 2acddc3d..b880dbd6 100644
--- a/src/lol/sys/threadtypes.h
+++ b/src/lol/sys/threadtypes.h
@@ -1,7 +1,7 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //            © 2013—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
 //
 //  Lol Engine is free software. It comes without any warranty, to
@@ -20,6 +20,8 @@
 
 #include "engine/entity.h"
 
+#include <map>
+
 namespace lol
 {
 
@@ -35,7 +37,7 @@ struct ThreadStatusBase : public StructSafeEnum
         THREAD_STOPPED,
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[NOTHING] = "NOTHING";
         enum_map[THREAD_STARTED] = "THREAD_STARTED";
@@ -57,7 +59,7 @@ struct ThreadJobTypeBase : public StructSafeEnum
         THREAD_STOP
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, String>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, String>& enum_map)
     {
         enum_map[NONE]          = "NONE";
         enum_map[WORK_TODO]     = "WORK_TODO";
@@ -238,10 +240,10 @@ public:
     virtual void TreatResult(ThreadJob* result);
 
 private:
-    uint32_t                m_frame_skip = 4;
-    uint32_t                m_frame_count = 0;
-    array<ThreadJob*>       m_job_done;
-    map<String, Status*>    m_files;
+    uint32_t m_frame_skip = 4;
+    uint32_t m_frame_count = 0;
+    array<ThreadJob*> m_job_done;
+    std::map<String, Status*> m_files;
 };
 typedef FileUpdateTester::Status FileUpdateStatus;
 
@@ -267,9 +269,9 @@ protected:
     virtual void TreatResult(ThreadJob* result);
 
 private:
-    image               m_dummy_image;
-    map<String, image*> m_images;
-    array<image*>       m_loaded_images;
+    image m_dummy_image;
+    std::map<String, image*> m_images;
+    array<image*> m_loaded_images;
 };
 
 } /* namespace lol */
diff --git a/src/lolimgui.h b/src/lolimgui.h
index d63b4f67..e306511d 100644
--- a/src/lolimgui.h
+++ b/src/lolimgui.h
@@ -14,6 +14,7 @@
 #pragma once
 
 #include <string>
+#include <map>
 
 //
 // The Imgui integration
@@ -112,7 +113,7 @@ class LolImGui : public Entity
             MAX = MOUSE_KEY_END,
         };
     protected:
-        virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+        virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
         {
             enum_map[Tab] = g_name_key_Tab;
             enum_map[LeftArrow] = g_name_key_Left;
@@ -162,7 +163,7 @@ class LolImGui : public Entity
             MAX = MOUSE_AXIS_END,
         };
     protected:
-        virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+        virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
         {
             enum_map[Scroll] = g_name_mouse_axis_scroll;
 
@@ -218,7 +219,7 @@ protected:
     InputDevice* m_mouse = nullptr;
     InputDevice* m_keyboard = nullptr;
     InputProfile m_profile;
-    //map<ImGuiKey_, LolImGuiKey> m_keys;
+    //std::map<ImGuiKey_, LolImGuiKey> m_keys;
     std::string m_clipboard;
 };
 
diff --git a/src/messageservice.h b/src/messageservice.h
index f9db0bde..fde0e567 100644
--- a/src/messageservice.h
+++ b/src/messageservice.h
@@ -14,6 +14,7 @@
 #pragma once
 
 #include <string>
+#include <map>
 
 //
 // The Message Service class
@@ -45,7 +46,7 @@ struct MessageBucketBase : public StructSafeEnum
         MAX
     };
 protected:
-    virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+    virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
     {
         enum_map[AppIn] = "AppIn";
         enum_map[AppOut] = "AppOut";
diff --git a/src/scene.cpp b/src/scene.cpp
index e48be37f..330417d5 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -1,7 +1,7 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010—2016 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //            © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
 //
 //  Lol Engine is free software. It comes without any warranty, to
@@ -13,6 +13,7 @@
 
 #include <lol/engine-internal.h>
 
+#include <map>
 #include <cstdlib>
 
 #if defined(_WIN32)
@@ -160,8 +161,8 @@ private:
      * - Updated by entity
      * - Marked Fire&Forget
      * - Scene is destroyed */
-    map<uintptr_t, array<PrimitiveRenderer*>> m_prim_renderers;
-    static map<uintptr_t, array<PrimitiveSource*>> m_prim_sources;
+    std::map<uintptr_t, array<PrimitiveRenderer*>> m_prim_renderers;
+    static std::map<uintptr_t, array<PrimitiveSource*>> m_prim_sources;
     static mutex m_prim_mutex;
 
     Camera *m_default_cam;
@@ -196,7 +197,7 @@ private:
     m_tile_api;
 };
 uint64_t SceneData::m_used_id = 1;
-map<uintptr_t, array<PrimitiveSource*>> SceneData::m_prim_sources;
+std::map<uintptr_t, array<PrimitiveSource*>> SceneData::m_prim_sources;
 mutex SceneData::m_prim_mutex;
 
 /*
@@ -364,8 +365,7 @@ void Scene::Reset()
     ASSERT(!!data, "Trying to access a non-ready scene");
 
     /* New scenegraph: Release fire&forget primitives */
-    array<uintptr_t> keys = data->m_prim_renderers.keys();
-    for (uintptr_t key : keys)
+    for (uintptr_t key : keys(data->m_prim_renderers))
     {
         for (int idx = 0; idx < data->m_prim_renderers[key].count(); ++idx)
             if (data->m_prim_renderers[key][idx]->m_fire_and_forget)
@@ -688,8 +688,7 @@ void Scene::render_primitives()
     rc.SetDepthFunc(DepthFunc::LessOrEqual);
 
     /* new scenegraph */
-    array<uintptr_t> keys = data->m_prim_renderers.keys();
-    for (uintptr_t key : keys)
+    for (uintptr_t key : keys(data->m_prim_renderers))
     {
         for (int idx = 0; idx < data->m_prim_renderers[key].count(); ++idx)
         {
diff --git a/src/sys/threadtypes.cpp b/src/sys/threadtypes.cpp
index 10b37bab..9e55047b 100644
--- a/src/sys/threadtypes.cpp
+++ b/src/sys/threadtypes.cpp
@@ -1,7 +1,7 @@
 //
 //  Lol Engine
 //
-//  Copyright © 2010—2017 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //            © 2014—2015 Benjamin “Touky” Huet <huet.benjamin@gmail.com>
 //
 //  Lol Engine is free software. It comes without any warranty, to
@@ -86,7 +86,7 @@ protected:
 //FileUpdateTester ------------------------------------------------------------
 FileUpdateTester::~FileUpdateTester()
 {
-    ASSERT(!m_files.count(), "Files need to be unregistered before destroying FileUpdateTester");
+    ASSERT(!m_files.size(), "Files need to be unregistered before destroying FileUpdateTester");
 }
 
 //File interface --------------------------------------------------------------
@@ -99,16 +99,16 @@ FileUpdateTester::Status* FileUpdateTester::RegisterFile(String const& path)
 
 void FileUpdateTester::UnregisterFile(String const& path)
 {
-    ASSERT(m_files.has_key(path));
+    ASSERT(has_key(m_files, path));
     delete m_files[path];
-    m_files.remove(path);
+    m_files.erase(path);
 }
 
 void FileUpdateTester::UnregisterFile(FileUpdateTester::Status*& status)
 {
     ASSERT(status);
-    array<String> keys = m_files.keys();
-    for (String key : keys)
+    array<String> all_keys = keys(m_files);
+    for (String key : all_keys)
     {
         if (m_files[key] == status)
         {
@@ -124,8 +124,8 @@ void FileUpdateTester::UnregisterFile(FileUpdateTester::Status*& status)
 void FileUpdateTester::TickGame(float seconds)
 {
     //Reset update for this frame
-    array<String> keys = m_files.keys();
-    for (String key : keys)
+    array<String> all_keys = keys(m_files);
+    for (String key : all_keys)
         m_files[key]->SetUpdated(false);
 
     super::TickGame(seconds);
@@ -217,7 +217,7 @@ void AsyncImageLoader::TreatResult(ThreadJob* result)
     if (job->GetJobType() == ThreadJobType::WORK_SUCCEEDED)
     {
         Image* src = m_images[job->GetPath()];
-        m_images.remove(job->GetPath());
+        m_images.erase(job->GetPath());
         src->Copy(job->GetImage());
         m_loaded_images.push_unique(src);
     }
diff --git a/src/t/base/enum.cpp b/src/t/base/enum.cpp
index 02f7eaf5..bc0dee81 100644
--- a/src/t/base/enum.cpp
+++ b/src/t/base/enum.cpp
@@ -15,6 +15,7 @@
 #include <lolunit.h>
 
 #include <string>
+#include <map>
 
 namespace lol
 {
@@ -33,7 +34,7 @@ lolunit_declare_fixture(enum_test)
             };
 
         protected:
-            virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+            virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
             {
                 enum_map[first] = "first";
                 enum_map[second] = "second";
diff --git a/src/t/base/map.cpp b/src/t/base/map.cpp
index 917abce6..6531d4aa 100644
--- a/src/t/base/map.cpp
+++ b/src/t/base/map.cpp
@@ -1,7 +1,7 @@
 //
 //  Lol Engine — Unit tests
 //
-//  Copyright © 2010—2015 Sam Hocevar <sam@hocevar.net>
+//  Copyright © 2010—2018 Sam Hocevar <sam@hocevar.net>
 //
 //  Lol Engine is free software. It comes without any warranty, to
 //  the extent permitted by applicable law. You can redistribute it
@@ -12,6 +12,8 @@
 
 #include <lol/engine-internal.h>
 
+#include <map>
+
 #include <lolunit.h>
 
 namespace lol
@@ -19,275 +21,16 @@ namespace lol
 
 lolunit_declare_fixture(map_test)
 {
-    lolunit_declare_test(map_declare)
-    {
-        map<uint8_t, uint8_t> m1;
-        map<int, int> m2;
-        map<float, float> m3;
-        map<char const *, char const *> m4;
-    }
-
-    lolunit_declare_test(map_set)
-    {
-        map<int, int> m;
-
-        for (int i = 0; i < 1000; i++)
-            m[i] = -1;
-
-        for (int i = 0; i < 1000; i++)
-            m[i] = i;
-
-        for (int i = 0; i < 1000; i++)
-            lolunit_assert_equal(m[i], i);
-    }
-
     lolunit_declare_test(map_has_key)
     {
-        map<int, int> m;
+        std::map<int, int> m;
 
         m[0] = 1;
         m[2] = 2;
 
-        lolunit_assert(m.has_key(0));
-        lolunit_assert(!m.has_key(1));
-        lolunit_assert(m.has_key(2));
-    }
-
-    lolunit_declare_test(map_remove)
-    {
-        map<uint64_t, uint64_t> m;
-        array<uint64_t> a;
-
-        for (int i = 0; i < 20; i++)
-        {
-            a << i;
-            m[i] = -1;
-        }
-        for (int i = 0; i < a.count(); i++)
-            m[i] = i;
-        a.shuffle();
-        for (int i = 0; i < a.count(); i++)
-            m.remove(a[i]);
-    }
-
-    lolunit_declare_test(map_remove_string)
-    {
-        map<std::string, uint64_t> m;
-        array<std::string> a;
-
-        for (int i = 0; i < 20; i++)
-        {
-            a << format("test_str_%i", i);
-            m[a.last()] = -1;
-        }
-        for (int i = 0; i < a.count(); i++)
-            m[a[i]] = i;
-        a.shuffle();
-        for (int i = 0; i < a.count(); i++)
-            m.remove(a[i]);
-    }
-
-    lolunit_declare_test(map_remove_bug)
-    {
-        map<uint64_t, uint64_t> m;
-
-        for (int i = 0; i < 20; i++)
-            m[i] = i;
-
-        for (int i : { 12, 0, 17, 2, 9, 4, 15, 10 })
-            m.remove(i);
-
-        lolunit_assert_equal(m[8], 8);
-    }
-
-    lolunit_declare_test(map_random_add_remove)
-    {
-        map<unsigned char, unsigned char> m;
-
-        unsigned char a = 1, b = 1, c = 1;
-
-        unsigned char presence[256];
-        unsigned char value[256];
-
-        for (int i = 0 ; i < 256 ; ++i)
-        {
-            presence[i] = 0;
-        }
-
-        for (int i = 0 ; i < 10000 ; ++i)
-        {
-            m[a] = b;
-            m.remove(b);
-
-            presence[a] = 1;
-            value[a] = b;
-            presence[b] = 0;
-
-            a = a * b + c;
-            b = b * c + a;
-            c = c * a + b;
-
-            for (int j = 0 ; j < 256 ; ++j)
-            {
-                unsigned char v;
-                if (presence[j])
-                {
-                    lolunit_assert(m.try_get(j, v));
-                    lolunit_assert_equal(value[j], v);
-                }
-                else
-                {
-                    lolunit_assert(!m.try_get(j, v));
-                }
-            }
-        }
-    }
-
-    lolunit_declare_test(string_map)
-    {
-        map<char const *, int> m;
-
-        m["foo"] = 42;
-        m["bar"] = 12;
-        m["baz"] = 2;
-
-        int foo = m["foo"];
-        int bar = m["bar"];
-        int baz = m["baz"];
-
-        lolunit_assert_equal(42, foo);
-        lolunit_assert_equal(12, bar);
-        lolunit_assert_equal(2, baz);
-
-        //Big stress test
-        array<String> bones =
-        {
-            "RootNode",
-            "Cyberano_Ns:Root_$AssimpFbx$_Translation",
-            "Cyberano_Ns:Box004_$AssimpFbx$_PreRotation",
-            "Cyberano_Ns:Root_$AssimpFbx$_PreRotation",
-            "Cyberano_Ns:Box004",
-            "Cyberano_Ns:Root_$AssimpFbx$_Rotation",
-            "Cyberano_Ns:Root",
-            "Cyberano_Ns:Hips",
-            "Cyberano_Ns:Spine",
-            "Cyberano_Ns:RightUpLeg",
-            "Cyberano_Ns:LeftUpLeg",
-            "Cyberano_Ns:BeltSheath1",
-            "Cyberano_Ns:RightCoat",
-            "Cyberano_Ns:LeftCoat",
-            "Cyberano_Ns:Spine1",
-            "Cyberano_Ns:RightLeg",
-            "Cyberano_Ns:RightUpLegRoll",
-            "Cyberano_Ns:LeftUpLegRoll",
-            "Cyberano_Ns:LeftLeg",
-            "Cyberano_Ns:Sheath",
-            "Cyberano_Ns:BeltSheath2",
-            "Cyberano_Ns:BeltSheath3",
-            "Cyberano_Ns:Spine2",
-            "Cyberano_Ns:FrontBelt1",
-            "Cyberano_Ns:BackBelt1",
-            "Cyberano_Ns:RightFoot",
-            "Cyberano_Ns:RightLegRoll",
-            "Cyberano_Ns:LeftLegRoll",
-            "Cyberano_Ns:LeftFoot",
-            "Cyberano_Ns:Sword",
-            "Cyberano_Ns:Neck",
-            "Cyberano_Ns:RightShoulder",
-            "Cyberano_Ns:LeftShoulder",
-            "Cyberano_Ns:Cloth",
-            "Cyberano_Ns:FrontBelt2",
-            "Cyberano_Ns:RightToeBase",
-            "Cyberano_Ns:LeftToeBase",
-            "Cyberano_Ns:Head",
-            "Cyberano_Ns:RightArm",
-            "Cyberano_Ns:RightSpaulder1",
-            "Cyberano_Ns:RightSpaulder2",
-            "Cyberano_Ns:LeftArm",
-            "Cyberano_Ns:LeftSpaulder1",
-            "Cyberano_Ns:LeftCloth01",
-            "Cyberano_Ns:MiddleCloth01",
-            "Cyberano_Ns:RightCloth01",
-            "Cyberano_Ns:FrontBelt3",
-            "Cyberano_Ns:RightoeEnd",
-            "Cyberano_Ns:LeftoeEnd",
-            "Cyberano_Ns:HeadEnd",
-            "Cyberano_Ns:Cap",
-            "Cyberano_Ns:RightForeArm",
-            "Cyberano_Ns:RightArmRoll",
-            "Cyberano_Ns:LeftForeArm",
-            "Cyberano_Ns:LeftArmRoll",
-            "Cyberano_Ns:LeftCloth02",
-            "Cyberano_Ns:MiddleCloth02",
-            "Cyberano_Ns:RightCloth02",
-            "Cyberano_Ns:Feather01",
-            "Cyberano_Ns:RightHand",
-            "Cyberano_Ns:RightForeArmRoll",
-            "Cyberano_Ns:LeftHand",
-            "Cyberano_Ns:LeftForeArmRoll",
-            "Cyberano_Ns:LeftCloth03",
-            "Cyberano_Ns:MiddleCloth03",
-            "Cyberano_Ns:RightCloth03",
-            "Cyberano_Ns:Feather02",
-            "Cyberano_Ns:RightThumb1",
-            "Cyberano_Ns:RightIndex1",
-            "Cyberano_Ns:RightMiddle1",
-            "Cyberano_Ns:RightRing1",
-            "Cyberano_Ns:RightCuff",
-            "Cyberano_Ns:LeftThumb1",
-            "Cyberano_Ns:LeftIndex1",
-            "Cyberano_Ns:LeftMiddle1",
-            "Cyberano_Ns:LeftRing1",
-            "Cyberano_Ns:LeftCloth04",
-            "Cyberano_Ns:MiddleCloth04",
-            "Cyberano_Ns:RightCloth04",
-            "Cyberano_Ns:Feather03",
-            "Cyberano_Ns:RightThumb2",
-            "Cyberano_Ns:RightIndex2",
-            "Cyberano_Ns:RightMiddle2",
-            "Cyberano_Ns:RightRing2",
-            "Cyberano_Ns:LeftThumb2",
-            "Cyberano_Ns:LeftIndex2",
-            "Cyberano_Ns:LeftMiddle2",
-            "Cyberano_Ns:LeftRing2",
-            "Cyberano_Ns:Feather04",
-            "Cyberano_Ns:RightThumb3",
-            "Cyberano_Ns:RightIndex3",
-            "Cyberano_Ns:RightMiddle3",
-            "Cyberano_Ns:RightRing3",
-            "Cyberano_Ns:LeftThumb3",
-            "Cyberano_Ns:LeftIndex3",
-            "Cyberano_Ns:LeftMiddle3",
-            "Cyberano_Ns:LeftRing3",
-            "Cyberano_Ns:Feather05",
-            "Cyberano_Ns:RightThumb4",
-            "Cyberano_Ns:RightIndex4",
-            "Cyberano_Ns:RightMiddle4",
-            "Cyberano_Ns:RightRing4",
-            "Cyberano_Ns:LeftThumb4",
-            "Cyberano_Ns:LeftIndex4",
-            "Cyberano_Ns:LeftMiddle4",
-            "Cyberano_Ns:LeftRing4",
-            "Cyberano_Ns:Feather06",
-            "Cyberano_Ns:Feather07",
-            "Cyberano_Ns:Feather08",
-            "Cyberano_Ns:Feather09",
-            "Cyberano_Ns:Feather10",
-            "Cyberano_Ns:Feather11",
-            "Cyberano_Ns:Feather12",
-            "Cyberano_Ns:Feather13",
-            "Cyberano_Ns:Feather14",
-            "Cyberano_Ns:Feather15",
-            "Cyberano_Ns:Feather16",
-            "Cyberano_Ns:Feather17"
-        };
-
-        map<String, int> bones_map;
-        for (int i = 0; i < bones.count(); ++i)
-            bones_map[bones[i]] = i;
-
-        for (int i = 0; i < bones.count(); ++i)
-            lolunit_assert_equal(bones_map[bones[i]], i);
+        lolunit_assert(has_key(m, 0));
+        lolunit_assert(!has_key(m, 1));
+        lolunit_assert(has_key(m, 2));
     }
 };
 
diff --git a/src/t/sys/thread.cpp b/src/t/sys/thread.cpp
index fde42d42..9e6bfbcd 100644
--- a/src/t/sys/thread.cpp
+++ b/src/t/sys/thread.cpp
@@ -14,6 +14,7 @@
 #include <lol/engine-internal.h>
 
 #include <string>
+#include <map>
 
 #include <lolunit.h>
 
@@ -63,7 +64,7 @@ lolunit_declare_fixture(thread_test)
                 DONE,
             };
         protected:
-            virtual bool BuildEnumMap(map<int64_t, std::string>& enum_map)
+            virtual bool BuildEnumMap(std::map<int64_t, std::string>& enum_map)
             {
                 enum_map[NOT_QUEUED] = "NOT_QUEUED";
                 enum_map[QUEUED] = "QUEUED";