src/generics/transform.h

changeset 1319
39d7a9642eea
parent 1072
9ce9496427f2
child 1326
69a90bd2dba2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/generics/transform.h	Sat Mar 24 11:57:24 2018 +0200
@@ -0,0 +1,93 @@
+/*
+ *  LDForge: LDraw parts authoring CAD
+ *  Copyright (C) 2013 - 2017 Teemu Piippo
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include <functional>
+
+//
+// TransformingIterator
+//
+// Transforming iterator, calls Fn on iterated values before returning them.
+//
+template<typename T, typename Res, typename Arg>
+struct TransformingIterator
+{
+	using Iterator = decltype(T().begin());
+	using Self = TransformingIterator<T, Res, Arg>;
+	Iterator it;
+	std::function<Res(Arg)> fn;
+
+	TransformingIterator(Iterator it, std::function<Res(Arg)> fn) :
+		it(it),
+		fn(fn) {}
+
+	Res operator*()
+	{
+		return fn(*it);
+	}
+
+	bool operator!= (const Self& other) const
+	{
+		return other.it != it;
+	}
+
+	void operator++()
+	{
+		++it;
+	}
+};
+
+//
+// TransformWrapper
+//
+// Transform object, only serves to produce transforming iterators
+//
+template<typename T, typename Res, typename Arg>
+struct TransformWrapper
+{
+	using Iterator = TransformingIterator<T, Res, Arg>;
+
+	TransformWrapper(T& iterable, std::function<Res(Arg)> fn) :
+		iterable(iterable),
+		function(fn) {}
+
+	Iterator begin()
+	{
+		return Iterator(iterable.begin(), function);
+	}
+
+	Iterator end()
+	{
+		return Iterator(iterable.end(), function);
+	}
+
+	T& iterable;
+	std::function<Res(Arg)> function;
+};
+
+template<typename T, typename Res, typename Arg>
+TransformWrapper<T, Res, Arg> transform(T& iterable, Res(*fn)(Arg))
+{
+	return TransformWrapper<T, Res, Arg>(iterable, fn);
+}
+
+template<typename T, typename Res, typename Arg>
+TransformWrapper<T, Res, Arg> transform(T& iterable, std::function<Res(Arg)> fn)
+{
+	return TransformWrapper<T, Res, Arg>(iterable, fn);
+}

mercurial