File indexing completed on 2024-04-21 05:42:27

0001 // clang-format off
0002 /*
0003  * KDiff3 - Text Diff And Merge Tool
0004  *
0005  * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 // clang-format on
0009 
0010 #ifndef COMBINERS_H
0011 #define COMBINERS_H
0012 
0013 #include <QtGlobal>
0014 
0015 #include <boost/signals2.hpp>
0016 #include <type_traits>
0017 
0018 struct or_
0019 {
0020     typedef bool result_type;
0021     template <typename InputIterator> bool operator()(InputIterator first, InputIterator last) const
0022     {
0023         // If there are no slots to call, just return true
0024         if(first == last) return true;
0025 
0026         bool ret = *first++;
0027         //return true if any slot returns true
0028         while(first != last)
0029         {
0030             if(!ret)
0031                 ret = *first;
0032             ++first;
0033         }
0034 
0035         return ret;
0036     }
0037 };
0038 
0039 struct and_
0040 {
0041     typedef bool result_type;
0042     template <typename InputIterator> bool operator()(InputIterator first, InputIterator last) const
0043     {
0044         // If there are no slots to call, just return true
0045         if(first == last) return true;
0046 
0047         bool ret = *first++;
0048         //return first non-true as if && were used
0049         while(ret && first != last)
0050         {
0051             ret = *first;
0052             ++first;
0053         }
0054 
0055         return ret;
0056     }
0057 };
0058 
0059 template<typename T> struct FirstNonEmpty
0060 {
0061     //This just provides a better error message if an inappropriate parameter is passed.
0062     static_assert(std::is_class<typename std::remove_reference<T>::type>(), "First parameter must be a class.");
0063     static_assert(std::is_same<decltype(std::declval<T>().isEmpty()), bool>(),
0064         "First parameter must implement or inherit isEmpty().");
0065 
0066     typedef T result_type;
0067     template <typename InputIterator> T operator()(InputIterator first, InputIterator last) const
0068     {
0069         // If there are no slots to call, just return empty container
0070         if(first == last) return T();
0071 
0072         T ret = *first++;
0073         //return first non-true as if && were used
0074         while(ret.isEmpty() && first != last)
0075         {
0076             ret = *first;
0077             ++first;
0078         }
0079 
0080         return ret;
0081     }
0082 };
0083 
0084 //Like 'or' but default to false if there are no connections and stops looking once true is returned.
0085 struct find
0086 {
0087     typedef bool result_type;
0088     template <typename InputIterator> bool operator()(InputIterator first, InputIterator last) const
0089     {
0090         // If there are no slots to call, just return true
0091         if(first == last)
0092             return false;
0093 
0094         bool found = *first++;
0095         //return true if any slot returns true
0096         while(first != last && !found)
0097         {
0098             found = *first;
0099             ++first;
0100         }
0101 
0102         return found;
0103     }
0104 };
0105 #ifdef BOOST_NO_EXCEPTIONS
0106 //Because boost doesn't define this
0107 inline void boost::throw_exception([[maybe_unused]] std::exception const& e)
0108 {
0109     std::terminate();
0110 }
0111 #endif
0112 
0113 #endif // !COMBINERS_H