Proton  1.1.1
Make porting easy from Python to C++11
set.hpp
1 #ifndef PROTON_SET_HEADER
2 #define PROTON_SET_HEADER
3 
4 #include <set>
5 #include <iterator>
6 #include <iostream>
7 
8 #include <proton/base.hpp>
9 #include <proton/pool.hpp>
10 #include <proton/ref.hpp>
11 
12 namespace proton{
13 
14 /** @addtogroup set_
15  * @{
16  */
17 
18 /** add an item in streaming style.
19  * @param x the set to be added
20  * @param val the new item
21  * @return the new x
22  */
23 template <typename T, typename C, typename A, typename V >
24 std::set<T,C,A>& operator<<(std::set<T,C,A>& x, V&& val)
25 {
26  x.insert(val);
27  return x;
28 }
29 
30 /** pop an item in streaming style.
31  * @param x the set to be popped from
32  * @param val the popped item
33  * @return the new x
34  */
35 template <typename T, typename C, typename A, typename V >
36 std::set<T,C,A>& operator>>(std::set<T,C,A>& x, V& val)
37 {
38  PROTON_THROW_IF(x.empty(), "want to pop an empty set.");
39  val=*x.begin();
40  x.erase(x.begin());
41  return x;
42 }
43 
44 /** general output for set.
45  * @param s the output stream
46  * @param x the set to be outputed
47  * @return s
48  */
49 template <typename T, typename C, typename A>
50 std::ostream& operator<<(std::ostream& s, const std::set<T,C,A>& x)
51 {
52  s << "{";
53  bool first=true;
54  for(auto& t: x){
55  if(first)
56  first=false;
57  else
58  s <<", ";
59  s << t;
60  }
61  s << "}";
62  return s;
63 }
64 
65 template <typename T, typename C, typename A>
66 std::wostream& operator<<(std::wostream& s, const std::set<T,C,A>& x)
67 {
68  s << L"{";
69  bool first=true;
70  for(auto& t: x){
71  if(first)
72  first=false;
73  else
74  s <<L", ";
75  s << t;
76  }
77  s << L"}";
78  return s;
79 }
80 
81 template <typename T, typename C, typename A>
82 void sort(std::set<T,C,A>& x)
83 {
84 }
85 
86 /** a set extension implementing python's set-like interfaces.
87  */
88 template<typename T, typename C=std::less<T>, typename A=smart_allocator<T> >
89 class set_ : public std::set<T,C,A>{
90 public:
91  typedef std::set<T,C,A> baseT;
92 
93 public:
94  /** forwarding ctor.
95  */
96  template<typename ...argT> set_(argT&& ...a):baseT(a...)
97  {}
98 
99  /** initializer_list forwarding ctor.
100  */
101  set_(std::initializer_list<T> a):baseT(a.begin(),a.end())
102  {}
103 
104  /** copy ctor.
105  */
106  set_(const set_& x):baseT(x)
107  {}
108 
109  /** move ctor.
110  */
111  set_(set_&& x)noexcept:baseT(x)
112  {}
113 
114  explicit set_(const baseT& x):baseT(x)
115  {}
116 
117  set_(baseT&& x)noexcept:baseT(x)
118  {}
119 
120  /** assign.
121  */
122  set_& operator=(const set_& x)
123  {
124  baseT::operator=(x);
125  return *this;
126  }
127 
128  set_& operator=(set_&& x)noexcept
129  {
130  baseT::operator=(x);
131  return *this;
132  }
133 
134  set_& operator=(const baseT& x)
135  {
136  baseT::operator=(x);
137  return *this;
138  }
139 
140  set_& operator=(baseT&& x)noexcept
141  {
142  baseT::operator=(x);
143  return *this;
144  }
145 
146  template<typename argT> set_& operator=(argT&& a)
147  {
148  baseT::operator=(a);
149  return *this;
150  }
151 
152  set_& operator=(std::initializer_list<T> a)
153  {
154  baseT::operator=(a);
155  return *this;
156  }
157 
158  /** cast to std::set<>&.
159  */
160  operator baseT&()
161  {
162  return reinterpret_cast<baseT&>(*this);
163  }
164 
166 
167  /** add an item.
168  */
169  void add(const T& x)
170  {
171  this->insert(x);
172  }
173 
174  void add(T&& x)
175  {
176  this->insert(x);
177  }
178 
179  /** pop an item from the sequence.
180  * @return the value.
181  * @throw proton::err if there is no any item.
182  */
183  T pop()
184  {
185  auto it=this->begin();
186  PROTON_THROW_IF(it==this->end(), "try to pop an empty set.");
187  T r=*it;
188  this->erase(it);
189  return r;
190  }
191 
192  /** remove a value.
193  * @param val the value.
194  * @throw std::invalid_argument if there is no such a value.
195  */
196  void remove(const T& val)
197  {
198  auto end=this->end();
199  auto it=this->find(val);
200  if(it==end)
201  throw std::invalid_argument("The given value doesn't exist in this sequence.");
202  this->erase(it);
203  }
204 
205  /** remove a value if it is present.
206  * @param val the value.
207  */
208  void discard(const T& val)
209  {
210  auto end=this->end();
211  auto it=this->find(val);
212  if(it!=end)
213  this->erase(it);
214  }
215 
216 };
217 
218 /**
219  * @example set.cpp
220  * [TODO]
221  */
222 
223 /** &=
224  */
225 template <typename T, typename C, typename A>
226 std::set<T,C,A>& operator&=(std::set<T,C,A>& x, const std::set<T,C,A>& y)
227 {
228  auto it=x.begin(), end=x.end();
229  while(it!=end){
230  if(!has(y,*it)){
231  auto it1=it;
232  ++it;
233  x.erase(it1);
234  }
235  else
236  ++it;
237  }
238  return x;
239 }
240 
241 /** |=
242  */
243 template <typename T, typename C, typename A>
244 std::set<T,C,A>& operator|=(std::set<T,C,A>& x, const std::set<T,C,A>& y)
245 {
246  for(auto& t: y){
247  x.insert(t);
248  }
249  return x;
250 }
251 
252 /** set & set
253  */
254 template <typename T, typename C, typename A>
255 set_<T,C,A> operator&(const std::set<T,C,A>& x, const std::set<T,C,A>& y)
256 {
257  set_<T,C,A> z;
258  std::set_intersection(x.begin(), x.end(),y.begin(),y.end(),std::inserter(z,z.begin()));
259  return z;
260 }
261 
262 
263 /** set | set
264  */
265 template <typename T, typename C, typename A>
266 set_<T,C,A> operator|(const std::set<T,C,A>& x, const std::set<T,C,A>& y)
267 {
268  set_<T,C,A> z;
269  std::set_union(x.begin(), x.end(),y.begin(),y.end(),std::inserter(z,z.begin()));
270  return z;
271 }
272 
273 /** cast to proton::set_<>& from std::set<>&.
274  */
275 template<typename T, typename C, typename A>
276 set_<T,C,A>& cast_(std::set<T,C,A>& x)
277 {
278  return reinterpret_cast<set_<T,C,A>&>(x);
279 }
280 
281 template<typename T, typename C, typename A>
282 const set_<T,C,A>& cast_(const std::set<T,C,A>& x)
283 {
284  return reinterpret_cast<const set_<T,C,A>&>(x);
285 }
286 
287 template<typename T, typename C, typename A>
288 set_<T,C,A>&& cast_(std::set<T,C,A>&& x)
289 {
290  return reinterpret_cast<set_<T,C,A>&&>(x);
291 }
292 
293 template<typename T, typename C, typename A>
294 const set_<T,C,A>&& cast_(const std::set<T,C,A>&& x)
295 {
296  return reinterpret_cast<const set_<T,C,A>&&>(x);
297 }
298 
299 /**
300  * @}
301  */
302 
303 namespace detail{
304 
305 template<typename T, typename C, typename allocT>
306 struct has_t<std::set<T,C,allocT> >{
307  template<typename V> static bool result(const std::set<T,C,allocT>& x, V&& v)
308  {
309  return x.find(v)!=x.end();
310  }
311 };
312 
313 template<typename T, typename C, typename allocT>
314 struct has_t<set_<T,C,allocT> >{
315  template<typename V> static bool result(const set_<T,C,allocT>& x, V&& v)
316  {
317  return x.find(v)!=x.end();
318  }
319 };
320 
321 } // ns detail
322 
323 } // ns proton
324 #endif // PROTON_SET_HEADER