YAP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
container_utils.h
Go to the documentation of this file.
1 /* YAP - Yet another PWA toolkit
2  Copyright 2015, Technische Universitaet Muenchen,
3  Authors: Daniel Greenwald, Johannes Rauch
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
20 
21 #ifndef yap_container_utils_h
22 #define yap_container_utils_h
23 
24 #include <algorithm>
25 
28 template <class InputIt1, class InputIt2, class BinaryPredicate>
29 bool overlap(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p)
30 {
31  using T1 = typename std::iterator_traits<InputIt1>::value_type;
32  using T2 = typename std::iterator_traits<InputIt2>::value_type;
33  return std::any_of(first1, last1, [&](const T1 & a) { return std::any_of(first2, last2, [&](const T2 & b) {return p(a, b);}); });
34 }
35 
38 template <class InputIt1, class InputIt2, class BinaryPredicate>
39 bool disjoint(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p)
40 {
41  using T1 = typename std::iterator_traits<InputIt1>::value_type;
42  using T2 = typename std::iterator_traits<InputIt2>::value_type;
43  return std::none_of(first1, last1, [&](const T1 & a) { return std::none_of(first2, last2, [&](const T2 & b) {return p(a, b);}); });
44 }
45 
48 template <class InputIt1, class InputIt2, class BinaryPredicate>
49 bool contains(InputIt1 first_haystack, InputIt1 last_haystack, InputIt2 first_needle, InputIt2 last_needle, BinaryPredicate p)
50 {
51  return std::all_of(first_needle, last_needle, [&](const typename std::iterator_traits<InputIt2>::value_type& b)
52  {return std::any_of(first_haystack, last_haystack, std::bind(p, std::placeholders::_1, b)); });
53 }
54 
57 template <class InputIt>
58 const bool orderless_equal(InputIt first1, InputIt last1, InputIt first2, InputIt last2)
59 {
60  return std::all_of(first1, last1, [&](const typename std::iterator_traits<InputIt>::value_type& a)
61  {return std::count(first1, last1, a) == std::count(first2, last2, a);});
62 }
63 
66 template <class InputIt>
67 const bool orderless_contains(InputIt first_haystack, InputIt last_haystack, InputIt first_needle, InputIt last_needle)
68 {
69  return std::all_of(first_needle, last_needle, [&](const typename std::iterator_traits<InputIt>::value_type& a)
70  {return std::count(first_needle, last_needle, a) <= std::count(first_haystack, last_haystack, a);});
71 }
72 
75 // \tparam Compare less-than comparitor
76 // \tparam BinaryPredicate equality comparitor
77 template <class InputIt/*, class Compare, class BinaryPredicate*/>
78 InputIt ordered_unique(InputIt first, InputIt last/*, Compare lt, BinaryPredicate eq*/)
79 {
80  // make vector of iterators
81  std::vector<InputIt> v;
82  v.reserve(std::distance(first, last));
83  for (InputIt i = first; i != last; ++i)
84  v.push_back(i);
85  // sort it
86  std::sort(v.begin(), v.end(), [](const InputIt & A, const InputIt & B) {return /*lt(*A, *B)*/ *A < *B;});
87  // apply unique to it
88  v.erase(std::unique(v.begin(), v.end(), [](const InputIt & A, const InputIt & B) {return /*eq(*A, *B)*/ *A == *B;}), v.end());
89  std::sort(v.begin(), v.end());
90 
91  size_t j = 0;
92  for (InputIt i = first; i != last && j != v.size(); ++i)
93  if (i == v[j]) {
94  std::iter_swap(i, first);
95  ++j;
96  ++first;
97  }
98 
99  return first;
100 }
101 
107 template <class InputIt>
108 std::vector<std::vector<typename InputIt::value_type> > combinations(InputIt first, InputIt last, size_t n)
109 {
110  // create vector of iterators initialized to first, first + 1, first + 2, ...
111  std::vector<InputIt> Its(n, last);
112  for (size_t i = 0; i < n; ++i)
113  Its[i] = first + i;
114 
115  // create output vector of vectors
116  std::vector<std::vector<typename InputIt::value_type> > C;
117 
118  // repeat until last iterator is at last
119  while (Its.back() < last) {
120 
121  // create combination vector from current state
122  std::vector<typename InputIt::value_type> v;
123  v.reserve(n);
124  for (const auto& it : Its)
125  v.push_back(*it);
126 
127  // add it to vector of combinations
128  C.push_back(v);
129 
130  // increment last iterator
131  ++Its.back();
132  // loop from iterators from back to first,
133  // checking if each if it's advanced to its furthestmost point
134  for (int i = Its.size() - 1; i >= 0 && Its[i] + (Its.size() - 1 - i ) >= last; --i) {
135  // if first iterator has advanced to furthermost point, set all to last
136  if (i == 0) {
137  for (auto& it : Its)
138  it = last;
139  } else {
140  // increase iterator before current iterator
141  ++Its[i - 1];
142  // reset all following iterators to be in sequence beyond that one
143  for (size_t j = i; j < Its.size(); ++j)
144  Its[j] = Its[j - 1] + 1;
145  }
146  }
147  }
148 
149  return C;
150 }
151 
153 
155 template <typename T>
156 bool overlap(const std::vector<T>& A, const std::vector<T>& B)
157 { return overlap(A.begin(), A.end(), B.begin(), B.end(), [](const T & a, const T & b) {return a == b;}); }
158 
160 template <typename T>
161 bool disjoint(const std::vector<T>& A, const std::vector<T>& B)
162 { return disjoint(A.begin(), A.end(), B.begin(), B.end(), [](const T & a, const T & b) {return a == b;}); }
163 
165 template <typename T>
166 bool contains(const std::vector<T>& A, const std::vector<T>& B)
167 { return contains(A.begin(), A.end(), B.begin(), B.end(), [](const T & a, const T & b) {return a == b;}); }
168 
169 // \return vector of combinations of elements in vector
170 template <typename T>
171 std::vector<std::vector<T> > combinations(const std::vector<T>& V, size_t n)
172 { return combinations(V.begin(), V.end(), n); }
173 
174 #endif
175 
bool contains(InputIt1 first_haystack, InputIt1 last_haystack, InputIt2 first_needle, InputIt2 last_needle, BinaryPredicate p)
Definition: container_utils.h:49
const bool orderless_equal(InputIt first1, InputIt last1, InputIt first2, InputIt last2)
Definition: container_utils.h:58
std::vector< std::vector< typename InputIt::value_type > > combinations(InputIt first, InputIt last, size_t n)
Definition: container_utils.h:108
InputIt ordered_unique(InputIt first, InputIt last)
Definition: container_utils.h:78
bool disjoint(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p)
Definition: container_utils.h:39
bool overlap(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p)
Definition: container_utils.h:29
const bool orderless_contains(InputIt first_haystack, InputIt last_haystack, InputIt first_needle, InputIt last_needle)
Definition: container_utils.h:67