File indexing completed on 2024-12-08 13:30:46
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