1 /*
2  * KDiff3 - Text Diff And Merge Tool
3  *
4  * SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
5  * SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #ifndef COMBINERS_H
9 #define COMBINERS_H
10 
11 #include <QtGlobal>
12 
13 #include <boost/signals2.hpp>
14 #include <type_traits>
15 
16 struct or
17 {
18     typedef bool result_type;
operatoror19     template <typename InputIterator> bool operator()(InputIterator first, InputIterator last) const
20     {
21         // If there are no slots to call, just return true
22         if(first == last) return true;
23 
24         bool ret = *first++;
25         //return true if any slot returns true
26         while(first != last)
27         {
28             if(!ret)
29                 ret = *first;
30             ++first;
31         }
32 
33         return ret;
34     }
35 };
36 
37 struct and
38 {
39     typedef bool result_type;
operatorand40     template <typename InputIterator> bool operator()(InputIterator first, InputIterator last) const
41     {
42         // If there are no slots to call, just return true
43         if(first == last) return true;
44 
45         bool ret = *first++;
46         //return first non-true as if && were used
47         while(ret && first != last)
48         {
49             ret = *first;
50             ++first;
51         }
52 
53         return ret;
54     }
55 };
56 
57 template<typename T> struct FirstNonEmpty
58 {
59     //This just provides a better error message if an in appropriate parameter is passed.
60     static_assert(std::is_class<typename std::remove_reference<T>::type>(), "First parameter must be a class.");
61     static_assert(std::is_same<decltype(std::declval<T>().isEmpty()), bool>(),
62         "First parameter must implement or inherit isEmpty().");
63 
64     typedef T result_type;
operatorFirstNonEmpty65     template <typename InputIterator> T operator()(InputIterator first, InputIterator last) const
66     {
67         // If there are no slots to call, just return empty container
68         if(first == last) return T();
69 
70         T ret = *first++;
71         //return first non-true as if && were used
72         while(ret.isEmpty() && first != last)
73         {
74             ret = *first;
75             ++first;
76         }
77 
78         return ret;
79     }
80 };
81 
82 #ifdef BOOST_NO_EXCEPTIONS
83 //Because boost doesn't define this
throw_exception(std::exception const & e)84 inline void boost::throw_exception(std::exception const& e) { Q_UNUSED(e); std::terminate();}
85 #endif
86 
87 #endif // !COMBINERS_H
88