diff --git a/SimoxUtility/CMakeLists.txt b/SimoxUtility/CMakeLists.txt
index 097c90cca106a402a43c6e2ce38c53bac8ed230b..35e638d7f012b8883c5910db8205e809cf660cab 100644
--- a/SimoxUtility/CMakeLists.txt
+++ b/SimoxUtility/CMakeLists.txt
@@ -82,6 +82,7 @@ SET(INCLUDES
     EigenStdVector.h
 
     algorithm/for_each_if.h
+    algorithm/apply.hpp
 
     color/cmaps/colormaps.h
     color/cmaps/Named.h
diff --git a/SimoxUtility/algorithm/apply.hpp b/SimoxUtility/algorithm/apply.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3dbbeee4a032be27825b02aaf32fb890004b8ef5
--- /dev/null
+++ b/SimoxUtility/algorithm/apply.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <functional>
+#include <map>
+#include <vector>
+
+
+namespace simox
+{
+
+
+    template <typename ValueIn, typename ValueOut>
+    ValueOut apply(const ValueIn& value, const std::function<ValueIn(ValueOut)>& op)
+    {
+        return op(value);
+    }
+
+
+    template <typename ValueIn, typename ValueOut>
+    std::vector<ValueOut> apply(const std::vector<ValueIn>& vector, const std::function<ValueIn(ValueOut)>& op)
+    {
+        std::vector<ValueOut> result;
+        std::transform(vector.begin(), vector.end(), std::back_inserter(result), [&op](const auto& v)
+        {
+            return apply(v, op);
+        });
+        return result;
+    }
+
+
+    template <typename ValueIn, typename ValueOut, typename Key>
+    std::map<Key, ValueOut> apply(const std::map<Key, ValueIn>& map, const std::function<ValueIn(ValueOut)>& op)
+    {
+        std::map<Key, ValueOut> result;
+        for (const auto& [name, value] : map)
+        {
+            result[name] = apply(value, op);
+        }
+        return result;
+    }
+
+
+}
+
diff --git a/SimoxUtility/color/ColorMap.h b/SimoxUtility/color/ColorMap.h
index 5ccda615c0fe09a3426c91b1aecd68f8b06e7e47..4c66557ecd626e1aa4baefb0415687cc75e4a116 100644
--- a/SimoxUtility/color/ColorMap.h
+++ b/SimoxUtility/color/ColorMap.h
@@ -4,6 +4,8 @@
 #include <map>
 #include <string>
 
+#include <SimoxUtility/algorithm/apply.hpp>
+
 #include "Color.h"
 #include "interpolation.h"
 
@@ -56,10 +58,10 @@ namespace simox::color
 
         /// Apply this colormap to a vector.
         template <typename V>
-        std::vector<Color> operator()(const std::vector<V>& vector) const;
+        std::vector<Color> operator()(const std::vector<V>& vector) const { return simox::apply(vector, *this); }
         /// Apply this colormap to a map.
         template <typename K, typename V>
-        std::map<K, Color> operator()(const std::map<K, V>& map) const;
+        std::map<K, Color> operator()(const std::map<K, V>& map) const { return simox::apply(map, *this); }
 
         std::string name() const { return _name; }
         void setName(const std::string& name) { this->_name = name; }
@@ -99,26 +101,6 @@ namespace simox::color
 
     };
 
-
-    template<typename V>
-    std::vector<Color> ColorMap::operator()(const std::vector<V>& vector) const
-    {
-        std::vector<Color> result;
-        std::transform(vector.begin(), vector.end(), std::back_inserter(result), *this);
-        return result;
-    }
-
-    template<typename K, typename V>
-    std::map<K, Color> ColorMap::operator()(const std::map<K, V>& map) const
-    {
-        std::map<K, Color> result;
-        for (const auto& [name, value] : map)
-        {
-            result[name] = (*this)(value);
-        }
-        return result;
-    }
-
 }