Mungojerrie  1.1
Mungojerrie
Set.hh
Go to the documentation of this file.
1 #ifndef SET_HH_
2 #define SET_HH_
3 
46 #include <set>
47 #include <iostream>
48 #include <type_traits>
49 #include <vector>
50 #include <unordered_set>
51 #include <list>
52 #include <forward_list>
53 #include <deque>
54 #include <map>
55 #include <unordered_map>
56 #include <tuple>
57 #include <array>
58 
60 template<typename Set1, typename Set2>
61 bool disjoint(Set1 const &set1, Set2 const &set2)
62 {
63  if (set1.empty() || set2.empty()) return true;
64 
65  typename Set1::const_iterator it1 = set1.begin(), it1End = set1.end();
66  typename Set2::const_iterator it2 = set2.begin(), it2End = set2.end();
67 
68  if (*it1 > *set2.rbegin() || *it2 > *set1.rbegin()) return true;
69 
70  while (it1 != it1End && it2 != it2End) {
71  if (*it1 == *it2) return false;
72  if (*it1 < *it2) { ++it1; }
73  else { ++it2; }
74  }
75  return true;
76 }
77 
79 template<typename Set1, typename Set2>
80 bool subsetOf(Set1 const & set1, Set2 const & set2)
81 {
82  if (set1.size() > set2.size()) return false;
83  for (auto const & e : set1) {
84  if (set2.find(e) == set2.end())
85  return false;
86  }
87  return true;
88 }
89 
91 template<typename Set1, typename Set2>
92 std::set<typename Set1::value_type> & operator|=(Set1 & lhs, Set2 const & rhs)
93 {
94  lhs.insert(rhs.cbegin(), rhs.cend());
95  return lhs;
96 }
97 
99 template<typename Set1, typename Set2>
100 std::set<typename Set1::value_type> operator|(Set1 set1, Set2 const & set2)
101 {
102  set1 |= set2;
103  return set1;
104 }
105 
107 template<typename Set1, typename Set2>
108 std::set<typename Set1::value_type> & operator&=(Set1 & lhs, Set2 const & rhs)
109 {
110  typename Set1::iterator it = lhs.begin();
111  while (it != lhs.end()) {
112  if (rhs.find(*it) == rhs.end())
113  it = lhs.erase(it);
114  else
115  ++it;
116  }
117  return lhs;
118 }
119 
121 template<typename Set1, typename Set2>
122 std::set<typename Set1::value_type> operator&(Set1 set1, Set2 const & set2)
123 {
124  set1 &= set2;
125  return set1;
126 }
127 
129 template<typename Set1, typename Set2>
130 std::set<typename Set1::value_type> & operator-=(Set1 & lhs, Set2 const & rhs)
131 {
132  for (auto const & e : rhs) {
133  lhs.erase(e);
134  if (lhs.size() == 0) break;
135  }
136  return lhs;
137 }
138 
140 template<typename Set1, typename Set2>
141 std::set<typename Set1::value_type> operator-(Set1 set1, Set2 const & set2)
142 {
143  set1 -= set2;
144  return set1;
145 }
146 
148 template<typename Set1, typename Set2>
149 std::set<typename Set1::value_type> & operator^=(Set1 & lhs, Set2 const & rhs)
150 {
151  for (auto const & e : rhs) {
152  auto it = lhs.find(e);
153  if (it != lhs.end())
154  lhs.erase(it);
155  else
156  lhs.insert(e);
157  }
158  return lhs;
159 }
160 
162 template<typename Set1, typename Set2>
163 std::set<typename Set1::value_type> operator^(Set1 set1, Set2 const & set2)
164 {
165  set1 ^= set2;
166  return set1;
167 }
168 
169 // Overloading of operator<< for vectors, sets, unordered_sets, deques, lists,
170 // forward_lists. Requires access to all members of container. So, it does
171 // not work with stacks and queues. It does not work with arrays either.
172 template<template<typename, typename...> class Container,
173  typename T,
174  typename = typename std::enable_if<std::is_same<std::vector<T>, Container<T> >::value ||
175  std::is_same<std::set<T>, Container<T> >::value ||
176  std::is_same<std::unordered_set<T>, Container<T> >::value ||
177  std::is_same<std::deque<T>, Container<T> >::value ||
178  std::is_same<std::list<T>, Container<T> >::value ||
179  std::is_same<std::forward_list<T>, Container<T> >::value
180  >::type,
181  typename ... Rest>
182 std::ostream & operator<<(std::ostream & os, Container<T, Rest...> const & s)
183 {
184  os << '{';
185  char sep[] = ",";
186  char * psep = sep + 1;
187  for (T const & e : s) {
188  os << psep << e;
189  psep = sep;
190  }
191  os << '}';
192  return os;
193 }
194 
195 // Overloading of operator<< for pairs.
196 template<typename F, typename S>
197 std::ostream & operator<<(std::ostream & os, std::pair<F, S> const & p)
198 {
199  os << '(' << p.first << ',' << p.second << ')';
200  return os;
201 }
202 
203 // Overloading of operator<< for maps.
204 template<template<typename, typename...> class Container,
205  typename Key, typename Val,
206  typename = typename std::enable_if<std::is_same<std::map<Key, Val>, Container<Key, Val> >::value || std::is_same<std::unordered_map<Key, Val>, Container<Key, Val> >::value>::type,
207  typename ... Rest>
208 std::ostream & operator<<(std::ostream & os, Container<Key, Val, Rest...> const & m)
209 {
210  os << '{';
211  char sep[] = ",";
212  char * psep = sep + 1;
213  for (std::pair<Key, Val> const e : m) {
214  os << psep << e;
215  psep = sep;
216  }
217  os << '}';
218  return os;
219 }
220 
221 // Overloading of operator<< for std::arrays.
222 template<typename T, size_t N>
223 std::ostream & operator<<(std::ostream & os, std::array<T, N> const & a)
224 {
225  os << '{';
226  char sep[] = ",";
227  char * psep = sep + 1;
228  for (T const & e : a) {
229  os << psep << e;
230  psep = sep;
231  }
232  os << '}';
233  return os;
234 }
235 
236 // Overloading of operator<< for C arrays. Arrays of chars are
237 // excluded to avoid ambiguity.
238 template<typename T,
239  typename = typename std::enable_if<!std::is_same<char, T>::value>::type,
240  size_t N>
241 std::ostream & operator<<(std::ostream & os, T const (&a)[N])
242 {
243  os << '{';
244  char sep[] = ",";
245  char * psep = sep + 1;
246  for (T const & e : a) {
247  os << psep << e;
248  psep = sep;
249  }
250  os << '}';
251  return os;
252 }
253 
254 
255 // Overloading of operator<< for tuples. Uses compile-time recursion.
256 template <typename T, size_t Size>
258  static std::ostream & print(std::ostream & os, T const & t) {
260  << (Size != 1 ? "," : "") << std::get<Size-1>(t);
261  }
262 };
263 
264 template <typename T>
265 struct print_tuple_aux<T, 0> {
266  static std::ostream & print(std::ostream & os, T const &) {
267  return os << '<';
268  }
269 };
270 
271 template <typename ...Args>
272 std::ostream & operator<<(std::ostream & os, std::tuple<Args...> const & t) {
273  using T = std::tuple<Args...>;
274  return print_tuple_aux<T, sizeof...(Args)>::print(os, t) << '>';
275 }
276 
277 #endif
operator&
std::set< typename Set1::value_type > operator&(Set1 set1, Set2 const &set2)
Definition: Set.hh:122
operator|
std::set< typename Set1::value_type > operator|(Set1 set1, Set2 const &set2)
Definition: Set.hh:100
disjoint
bool disjoint(Set1 const &set1, Set2 const &set2)
Definition: Set.hh:61
operator^=
std::set< typename Set1::value_type > & operator^=(Set1 &lhs, Set2 const &rhs)
Definition: Set.hh:149
operator-
std::set< typename Set1::value_type > operator-(Set1 set1, Set2 const &set2)
Definition: Set.hh:141
print_tuple_aux
Definition: Set.hh:257
subsetOf
bool subsetOf(Set1 const &set1, Set2 const &set2)
Definition: Set.hh:80
operator|=
std::set< typename Set1::value_type > & operator|=(Set1 &lhs, Set2 const &rhs)
Definition: Set.hh:92
operator^
std::set< typename Set1::value_type > operator^(Set1 set1, Set2 const &set2)
Definition: Set.hh:163
operator&=
std::set< typename Set1::value_type > & operator&=(Set1 &lhs, Set2 const &rhs)
Definition: Set.hh:108
operator-=
std::set< typename Set1::value_type > & operator-=(Set1 &lhs, Set2 const &rhs)
Definition: Set.hh:130