diff -r 3e92760fe00a -r f7dd937667a5 src/functional.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/functional.h Fri Feb 28 19:24:33 2020 +0200
@@ -0,0 +1,159 @@
+/*
+ * LDForge: LDraw parts authoring CAD
+ * Copyright (C) 2020 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 .
+ */
+
+#pragma once
+#include
+#include
+#include
+#include
+#include
+
+namespace fn
+{
+ template
+ class InsertIterator;
+}
+
+/**
+ * Like std::back_inserter but calls x.insert(v) instead
+ */
+template
+class fn::InsertIterator
+{
+public:
+ InsertIterator(C& container) :
+ container{container} {}
+ auto operator*()
+ {
+ return *this;
+ }
+ auto operator++()
+ {
+ return *this;
+ }
+ auto operator++(int)
+ {
+ return *this;
+ }
+ template
+ auto operator=(T&& value)
+ {
+ this->container.insert(std::forward(value));
+ return *this;
+ }
+private:
+ C& container;
+};
+
+namespace fn
+{
+ // Constructs a fn::InsertIterator
+ template
+ InsertIterator makeInsertIterator(C& container)
+ {
+ return InsertIterator{container};
+ }
+
+ // Constructs a back_inserter for std::vector
+ template
+ auto makeDefaultInserter(std::vector& vec)
+ {
+ return std::back_inserter(vec);
+ }
+
+ // Constructs a back_inserter for QVector
+ template
+ auto makeDefaultInserter(QVector& vec)
+ {
+ return std::back_inserter(vec);
+ }
+
+ // Constructs a back_inserter for QList
+ template
+ auto makeDefaultInserter(QList& vec)
+ {
+ return std::back_inserter(vec);
+ }
+
+ // Constructs an fn::InsertIterator for QSet
+ template
+ auto makeDefaultInserter(QSet& vec)
+ {
+ return InsertIterator(vec);
+ }
+
+ // Changes the value type of C
+ template
+ struct ChangeContainerValueType
+ {
+ };
+
+ // Changes the value type of std::vector
+ template
+ struct ChangeContainerValueType, TT>
+ {
+ using type = std::vector;
+ };
+
+ // Changes the value type of QVector
+ template
+ struct ChangeContainerValueType, TT>
+ {
+ using type = QVector;
+ };
+
+ // Changes the value type of QSet
+ template
+ struct ChangeContainerValueType, TT>
+ {
+ using type = QSet;
+ };
+
+ // Changes the value type of QList
+ template
+ struct ChangeContainerValueType, TT>
+ {
+ using type = QList;
+ };
+
+ // Changes the value type of C
+ template
+ using ChangeContainerValueType_t = typename ChangeContainerValueType::type;
+
+ /**
+ * \brief Applies \c function to all elements of \c container
+ * \param container Container to iterate
+ * \param function Function to apply
+ * \param Rt result type. If not provided, a suitable result type is deduced from inputs
+ * \returns mapped result container
+ */
+ template
+ auto map(C&& container, Fn&& function)
+ {
+ using value_t = decltype(*std::declval().begin());
+ using newvalue_t = std::result_of_t;
+ using result_t = std::conditional_t<
+ std::is_same_v