--- a/src/functional.h Tue Jun 28 19:36:03 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,190 +0,0 @@ -/* - * 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 <http://www.gnu.org/licenses/>. - */ - -#pragma once -#include <algorithm> -#include <functional> -#include <QVector> -#include <QSet> -#include <QList> - -namespace fn -{ - template<typename C> - class InsertIterator; -} - -/** - * Like std::back_inserter but calls x.insert(v) instead - */ -template<typename C> -class fn::InsertIterator -{ -public: - InsertIterator(C& container) : - container{container} {} - auto operator*() - { - return *this; - } - auto operator++() - { - return *this; - } - auto operator++(int) - { - return *this; - } - template<typename T> - auto operator=(T&& value) - { - this->container.insert(std::forward<T>(value)); - return *this; - } -private: - C& container; -}; - -namespace fn -{ - // Constructs a fn::InsertIterator - template<typename C> - InsertIterator<C> makeInsertIterator(C& container) - { - return InsertIterator<C>{container}; - } - - // Constructs a back_inserter for std::vector - template<typename T> - auto makeDefaultInserter(std::vector<T>& vec) - { - return std::back_inserter(vec); - } - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - // In Qt6 QVector is now a QList instead, so we need to disable this - // Constructs a back_inserter for QVector - template<typename T> - auto makeDefaultInserter(QVector<T>& vec) - { - return std::back_inserter(vec); - } -#endif - - template<typename T> - auto makeDefaultInserter(QList<T>& vec) - { - return std::back_inserter(vec); - } - - // Constructs an fn::InsertIterator for QSet - template<typename T> - auto makeDefaultInserter(QSet<T>& vec) - { - return InsertIterator(vec); - } - - // Changes the value type of C - template<typename C, typename TT> - struct ChangeContainerValueType - { - }; - - // Changes the value type of std::vector - template<typename T, typename TT> - struct ChangeContainerValueType<std::vector<T>, TT> - { - using type = std::vector<TT>; - }; - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - // Changes the value type of QVector - template<typename T, typename TT> - struct ChangeContainerValueType<QVector<T>, TT> - { - using type = QVector<TT>; - }; -#endif - - // Changes the value type of QSet - template<typename T, typename TT> - struct ChangeContainerValueType<QSet<T>, TT> - { - using type = QSet<TT>; - }; - - // Changes the value type of QList - template<typename T, typename TT> - struct ChangeContainerValueType<QList<T>, TT> - { - using type = QList<TT>; - }; - - // Changes the value type of C - template<typename C, typename TT> - using ChangeContainerValueType_t = typename ChangeContainerValueType<C, TT>::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<typename Rt = void, typename C, typename Fn> - auto map(C&& container, Fn&& function) - { - using value_t = decltype(*std::declval<C>().begin()); - using newvalue_t = std::result_of_t<Fn(value_t)>; - using result_t = std::conditional_t< - std::is_same_v<Rt, void>, - ChangeContainerValueType_t<std::remove_reference_t<C>, newvalue_t>, - Rt>; - result_t result; - result.reserve(std::end(container) - std::begin(container)); - std::transform(std::begin(container), std::end(container), makeDefaultInserter(result), function); - return result; - } -} - -template<typename T, typename Fn> -bool any(T&& container, Fn&& f) -{ - for (auto&& x : container) - { - if (f(x)) - { - return true; - } - } - return false; -} - - -template<typename T, typename Fn> -bool all(T&& container, Fn&& f) -{ - for (auto&& x : container) - { - if (not f(x)) - { - return false; - } - } - return true; -}