Easemob Windows SDK
emstl.h
1 //
2 // emstl.h
3 // easemob
4 //
5 // Created by linan on 16/3/8.
6 //
7 //
8 
9 #ifndef emstl_h
10 #define emstl_h
11 
12 #include <assert.h>
13 #include <map>
14 #include <mutex>
15 #include <set>
16 #include <vector>
17 
18 namespace easemob
19 {
20 //--------------------- provide concurrent safe stl wrapper ---------------------
21 // example
22 // void testVector() {
23 // EMVector<int> v;
24 // v.push_back(0);
25 // v.push_back(1);
26 // v.push_back(2);
27 //
28 // synchronize(v, [&](){
29 // int i = 0;
30 // for (vector<int>::iterator iter = v.begin(); iter != v.end(); ++iter) {
31 // cout << "v[" << i << "]:" << *iter << endl;
32 // i++;
33 // }
34 // });
35 //
36 // cout << "operator v[2]:" << v[2] << endl;
37 // }
38 
39 // notice: not contain vector<bool> wrapper
40 // synchronize braces should enclose iterator operations
41 // add new method:
42 // get: return inner reference, remember enclose it with synchronize braces
43 // clone: return a cloned object from inner object
44 //
45 // notice:
46 // synchronize function has limitation, following case is a liable use case and misused:
47 // synchronize(mMyGroups, [&](){
48 // if (mMyGroups.find(msg->conversationId()) != mMyGroups.end())
49 // {
50 // return true;
51 // }
52 // });
53 // the original purpose is if reach the condition, return.
54 // but in synchronize(obj, lamda), lamda return only return from synchronize scope.
55 // Please using following code instead:
56 // std::lock_guard<std::recursive_mutex> lock(mMyGroups.getMutex());
57 //
58 // limitation:
59 // not fully support initializer_list, cripple in supporting empty braces, such as:
60 // EMVector<int> v = {}; // not support
61 // EMVector<int> v1 = {1}; // ok
62 // EMMap<int, std::string> m = {}; // not support
63 // EMMap<std::string, float> m1 = {{"", 10.2f}, {"", 10.0f}}; // ok
64 
65  typedef std::function<void()> EMProcedure;
66 
67  class EMSTLBase {
68  public:
69  std::recursive_mutex &getMutex() { return mMutex; }
70  protected:
71  std::recursive_mutex mMutex;
72  };
73 
74  inline void synchronize(EMSTLBase &obj, EMProcedure procedure) {
75  std::lock_guard<std::recursive_mutex> lock(obj.getMutex());
76  procedure();
77  }
78 
79 #ifndef _WIN32
80 #ifndef _LIBCPP_INLINE_VISIBILITY
81 #define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__))
82 #endif
83 #else
84 #define _LIBCPP_INLINE_VISIBILITY
85 #endif
86 
87  // this macro help evade dead lock
88 #define _lock_both(obj0, obj1) \
89  assert(&obj0 != &obj1); \
90  std::unique_lock<std::recursive_mutex> _lock0((obj0).getMutex(), std::defer_lock); \
91  std::unique_lock<std::recursive_mutex> _lock1((obj1).getMutex(), std::defer_lock); \
92  if (&(obj0) < &(obj1)) { \
93  _lock0.lock(); \
94  _lock1.lock(); \
95  } else { \
96  _lock1.lock(); \
97  _lock0.lock(); \
98  }
99 
100 
101  template <typename T >
102  class EMVector : public EMSTLBase {
103  public:
104  typedef typename std::vector<T>::iterator iterator;
105  typedef typename std::vector<T>::const_iterator const_iterator;
106  typedef typename std::vector<T>::reverse_iterator reverse_iterator;
107  typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
108  typedef typename std::vector<T>::size_type size_type;
109  typedef typename std::vector<T>::allocator_type allocator_type;
110  typedef typename std::vector<T>::value_type value_type;
111  typedef T & reference;
112  typedef const T & const_reference;
113 
114  explicit EMVector (const allocator_type& alloc = allocator_type()) {
115  std::vector<T> v = std::vector<T>(alloc);
116  _vector = v;
117  }
118 
119  explicit EMVector (size_type n, const value_type& val = value_type(),
120  const allocator_type& alloc = allocator_type()) {
121  std::vector<T> v = std::vector<T>(n, val, alloc);
122  _vector = v;
123  }
124 
125  template <class InputIterator>
126  EMVector (InputIterator first, InputIterator last,
127  const allocator_type& alloc = allocator_type()) {
128  std::vector<T> v = std::vector<T>(first, last, alloc);
129  _vector = v;
130  }
131 
132  virtual ~EMVector() {
133  }
134 
135  EMVector(const std::vector<T> &v) {
136  _vector = v;
137  }
138 
139  EMVector(const EMVector<T> &v) {
140  std::lock_guard<std::recursive_mutex> lock(const_cast<EMVector<T>&>(v).getMutex());
141  _vector = v.get();
142  }
143 
144 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
145  EMVector(std::vector<T> &&v) {
146  _vector = std::move(v);
147  }
148 
149  EMVector(EMVector<T> &&v) {
150  std::lock_guard<std::recursive_mutex> lock(v.getMutex());
151  _vector.swap(v._vector);
152  v._vector.clear();
153  }
154 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
155 
156  inline EMVector & operator=(const EMVector<T> &v) {
157  if (this == &v) {
158  return *this;
159  }
160  EMVector<T> *_v = const_cast<EMVector<T>*>(&v);
161  _lock_both(*this, *_v);
162  _vector = v.get();
163  return *this;
164  }
165 
166  inline EMVector & operator=(const std::vector<T> &v) {
167  std::lock_guard<std::recursive_mutex> lock(getMutex());
168  if (&_vector != &v) {
169  _vector = v;
170  }
171  return *this;
172  }
173 
174 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
175  inline EMVector & operator=(EMVector<T> &&v) {
176  _lock_both(*this, v);
177  _vector = std::move(v.get());
178  return *this;
179  }
180 
181  inline EMVector & operator=(std::vector<T> &&v) {
182  std::lock_guard<std::recursive_mutex> lock(getMutex());
183  _vector = std::move(v);
184  return *this;
185  }
186 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
187 
188  inline const std::vector<T> & get() const {
189  return _vector;
190  }
191 
192  inline std::vector<T> clone() const {
193  EMVector<T> *temp = const_cast<EMVector<T>*>(this);
194  std::lock_guard<std::recursive_mutex> lock(temp->getMutex());
195  return _vector;
196  }
197 
198 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
199  _LIBCPP_INLINE_VISIBILITY
200  EMVector(std::initializer_list<value_type> __il) {
201  _vector = __il;
202  }
203  _LIBCPP_INLINE_VISIBILITY
204  EMVector(std::initializer_list<value_type> __il, const allocator_type& __a) {
205  _vector = std::vector<value_type>(__il, __a);
206  }
207  _LIBCPP_INLINE_VISIBILITY
208  inline EMVector & operator=(std::initializer_list<value_type> &&__il) {
209  std::lock_guard<std::recursive_mutex> lock(getMutex());
210  _vector = std::vector<value_type>(std::forward(__il));
211  return *this;
212  }
213 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
214 
215  //--------------------- modifier ---------------------
216  inline const T & operator[](size_type n) const {
217  EMVector<T> *temp = const_cast<EMVector<T>*>(this);
218  std::lock_guard<std::recursive_mutex> lock(temp->getMutex());
219  return _vector[n];
220  }
221 
222  inline void assign(iterator first, iterator last) {
223  std::lock_guard<std::recursive_mutex> lock(getMutex());
224  _vector.assign(first, last);
225  }
226 
227  inline void assign(size_type n, const T &val) {
228  std::lock_guard<std::recursive_mutex> lock(getMutex());
229  _vector.assign(n, val);
230  }
231 
232  inline void push_back(const T &val) {
233  std::lock_guard<std::recursive_mutex> lock(getMutex());
234  _vector.push_back(val);
235  }
236 
237  inline void pop_back(const T &val) {
238  std::lock_guard<std::recursive_mutex> lock(getMutex());
239  _vector.pop_back(val);
240  }
241 
242  inline void insert(iterator position, T &val) {
243  std::lock_guard<std::recursive_mutex> lock(getMutex());
244  _vector.insert(position, val);
245  }
246 
247  inline void insert (iterator position, size_type n, const value_type& val) {
248  std::lock_guard<std::recursive_mutex> lock(getMutex());
249  _vector.insert(position, n, val);
250  }
251 
252  template <class InputIterator>
253  inline void insert (iterator position, InputIterator first, InputIterator last) {
254  std::lock_guard<std::recursive_mutex> lock(getMutex());
255  _vector.insert(position, first, last);
256  }
257 
258  inline iterator erase(iterator position) {
259  std::lock_guard<std::recursive_mutex> lock(getMutex());
260  return _vector.erase(position);
261  }
262 
263  inline iterator erase (iterator first, iterator last) {
264  std::lock_guard<std::recursive_mutex> lock(getMutex());
265  return _vector.erase(first, last);
266  }
267 
268  inline void swap(std::vector<T>& x) {
269  std::lock_guard<std::recursive_mutex> lock(getMutex());
270  _vector.swap(x);
271  }
272 
273  inline void swap(EMVector<T>& x) {
274  _lock_both(*this, x);
275  _vector.swap(x);
276  }
277 
278  inline void clear() {
279  std::lock_guard<std::recursive_mutex> lock(getMutex());
280  _vector.clear();
281  }
282 
283  //--------------------- Capacity ---------------------
284  inline size_type size() const {
285  return _vector.size();
286  }
287 
288  inline size_type max_size() const {
289  return _vector.max_size();
290  }
291 
292  inline void resize (size_type n, value_type val = value_type()) {
293  std::lock_guard<std::recursive_mutex> lock(getMutex());
294  return _vector.resize(n, val);
295  }
296 
297  inline size_type capacity() const {
298  return _vector.capacity();
299  }
300 
301  inline bool empty() const {
302  return _vector.empty();
303  }
304 
305  inline void reserve (size_type n) {
306  std::lock_guard<std::recursive_mutex> lock(getMutex());
307  _vector.reserve(n);
308  }
309 
310  inline void shrink_to_fit() {
311  std::lock_guard<std::recursive_mutex> lock(getMutex());
312  _vector.shrink_to_fit();
313  }
314 
315  //--------------------- Element access ---------------------
316  inline T & operator[](size_type n) {
317  std::lock_guard<std::recursive_mutex> lock(getMutex());
318  return _vector[n];
319  }
320 
321  inline reference at (size_type n) {
322  std::lock_guard<std::recursive_mutex> lock(getMutex());
323  return _vector[n];
324  }
325 
326  inline const_reference at (size_type n) const {
327  std::lock_guard<std::recursive_mutex> lock(getMutex());
328  return _vector[n];
329  }
330 
331  inline reference front() {
332  std::lock_guard<std::recursive_mutex> lock(getMutex());
333  return _vector.front();
334  }
335 
336  inline const_reference front() const {
337  std::lock_guard<std::recursive_mutex> lock(getMutex());
338  return _vector.front();
339  }
340 
341  inline reference back() {
342  std::lock_guard<std::recursive_mutex> lock(getMutex());
343  return _vector.back();
344  }
345 
346  inline const_reference back() const {
347  std::lock_guard<std::recursive_mutex> lock(getMutex());
348  return _vector.back();
349  }
350 
351  // not thread safe, deprecated
352 // value_type* data() ;
353 // const value_type* data() const ;
354 
355  //--------------------- Iterator ---------------------
356  inline iterator begin() {
357  return _vector.begin();
358  }
359 
360  inline const_iterator begin() const {
361  return _vector.begin();
362  }
363  inline iterator end() {
364  return _vector.end();
365  }
366 
367  inline const_iterator end() const {
368  return _vector.end();
369  }
370 
371  inline reverse_iterator rbegin() {
372  return _vector.rbegin();
373  }
374 
375  inline const_reverse_iterator rbegin() const {
376  return _vector.rbegin();
377  }
378 
379  inline reverse_iterator rend() {
380  return _vector.rend();
381  }
382 
383  inline const_reverse_iterator rend() const {
384  return _vector.rend();
385  }
386 
387  inline const_iterator cbegin() const {
388  return _vector.cbegin();
389  }
390 
391  inline const_iterator cend() const {
392  return _vector.cend();
393  }
394 
395  inline const_reverse_iterator crbegin() const {
396  return _vector.crbegin();
397  }
398 
399  inline const_reverse_iterator crend() const {
400  return _vector.crend();
401  }
402 
403  private:
404  std::vector<T> _vector;
405  };
406 
407  template <class _Key, class _Tp, class _Compare = std::less<_Key>,
408  class _Allocator = std::allocator<std::pair<const _Key, _Tp> > >
409  class EMMap : public EMSTLBase {
410  public:
411  typedef _Key key_type;
412  typedef _Tp mapped_type;
413  typedef typename std::map<_Key, _Tp>::iterator iterator;
414  typedef typename std::map<_Key, _Tp>::const_iterator const_iterator;
415  typedef typename std::map<_Key, _Tp>::reverse_iterator reverse_iterator;
416  typedef typename std::map<_Key, _Tp>::const_reverse_iterator const_reverse_iterator;
417  typedef typename std::map<_Key, _Tp>::size_type size_type;
418  typedef typename std::pair<const _Key, _Tp> value_type;
419  typedef typename std::map<_Key, _Tp>::key_compare key_compare;
420  typedef typename std::map<_Key, _Tp>::allocator_type allocator_type;
421 
422  explicit EMMap (const key_compare& comp = key_compare(),
423  const allocator_type& alloc = allocator_type()) {
424  std::map<_Key, _Tp> m = std::map<_Key, _Tp>(comp, alloc);
425  _map = m;
426  }
427 
428  template <class InputIterator>
429  EMMap (InputIterator first, InputIterator last,
430  const key_compare& comp = key_compare(),
431  const allocator_type& alloc = allocator_type()) {
432  std::map<_Key, _Tp> m = std::map<_Key, _Tp>(first, last, comp, alloc);
433  _map = m;
434  }
435 
436  inline EMMap(const std::map<_Key, _Tp> &v_) {
437  _map = v_;
438  }
439 
440  virtual ~EMMap() {
441  }
442 
444  std::lock_guard<std::recursive_mutex> lock(const_cast<EMMap<key_type, mapped_type>&>(v).getMutex());
445  _map = v.get();
446  }
447 
448  inline EMMap & operator=(const EMMap<key_type, mapped_type> &v) {
449  if (this == &v) {
450  return *this;
451  }
453  _lock_both(*this, *_v);
454  _map = v.get();
455  return *this;
456  }
457 
458  inline EMMap & operator=(const std::map<key_type, mapped_type> &v) {
459  std::lock_guard<std::recursive_mutex> lock(getMutex());
460  if (&_map != &v) {
461  _map = v;
462  }
463  return *this;
464  }
465 
466 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
467  EMMap(std::map<key_type, mapped_type> &&v) {
468  _map = std::move(v);
469  }
470 
472  std::lock_guard<std::recursive_mutex> lock(v.getMutex());
473  std::swap(_map, v._map);
474  v._map.clear();
475  }
476 
477  inline EMMap & operator=(EMMap<key_type, mapped_type> &&v) {
478  _lock_both(*this, v);
479  std::swap(_map, v._map);
480  v._map.clear();
481  return *this;
482  }
483 
484  inline EMMap & operator=(std::map<key_type, mapped_type> &&v) {
485  std::lock_guard<std::recursive_mutex> lock(getMutex());
486  _map = std::move(v);
487  return *this;
488  }
489 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
490 
491  inline const std::map<_Key, _Tp> & get() const {
492  return _map;
493  }
494 
495  inline std::map<_Key, _Tp> clone() const {
497  std::lock_guard<std::recursive_mutex> lock(temp->getMutex());
498  return _map;
499  }
500 
501 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
502  _LIBCPP_INLINE_VISIBILITY
503  EMMap(std::initializer_list<value_type> __il, const key_compare& __comp = key_compare())
504  {
505  _map = std::map<_Key, _Tp>(__comp);
506  _map.insert(__il.begin(), __il.end());
507  }
508 
509  _LIBCPP_INLINE_VISIBILITY
510  EMMap(std::initializer_list<value_type> __il, const key_compare& __comp, const allocator_type& __a)
511  {
512  _map = std::map<_Key, _Tp>(__comp);
513  _map.insert(__il.begin(), __il.end());
514  }
515 
516 #if _LIBCPP_STD_VER > 11
517  _LIBCPP_INLINE_VISIBILITY
518  EMMap(std::initializer_list<value_type> __il, const allocator_type& __a)
519  : _map(__il, key_compare(), __a) {}
520 #endif
521 
522  _LIBCPP_INLINE_VISIBILITY
523  inline EMMap& operator=(std::initializer_list<value_type> __il)
524  {
525  _map.insert(__il.begin(), __il.end());
526  return *this;
527  }
528 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
529 
530  //--------------------- modifier ---------------------
531 
532  inline std::pair<iterator,bool> insert (const value_type& val) {
533  std::lock_guard<std::recursive_mutex> lock(getMutex());
534  return _map.insert(val);
535  }
536 
537  inline iterator insert (iterator position, const value_type& val) {
538  std::lock_guard<std::recursive_mutex> lock(getMutex());
539  return _map.insert(position, val);
540  }
541 
542  inline void insert(const_iterator first, const_iterator last) {
543  std::lock_guard<std::recursive_mutex> lock(getMutex());
544  return _map.insert(first, last);
545  }
546 
547  // erase return type, http://cplusplush.com/map/map/erase/ definition is mismatched with gnustl/xcode code
548  inline iterator erase (iterator position) {
549  std::lock_guard<std::recursive_mutex> lock(getMutex());
550  return _map.erase(position);
551  }
552 
553  inline size_type erase(const key_type& k) {
554  std::lock_guard<std::recursive_mutex> lock(getMutex());
555  return _map.erase(k);
556  }
557 
558  inline iterator erase(iterator first, iterator last) {
559  std::lock_guard<std::recursive_mutex> lock(getMutex());
560  return _map.erase(first, last);
561  }
562 
563  inline void swap (std::map<_Key, _Tp>& x) {
564  std::lock_guard<std::recursive_mutex> lock(getMutex());
565  _map.swap(x);
566  }
567 
568  inline void swap (EMMap<_Key, _Tp>& x) {
569  _lock_both(*this, x);
570  _map.swap(x.get());
571  }
572 
573  inline void clear() {
574  std::lock_guard<std::recursive_mutex> lock(getMutex());
575  _map.clear();
576  }
577 
578  // emplace
579  // Construct and insert element (public member function )
580  // emplace_hint
581  // Construct and insert element with hint (public member function )
582 
583  //--------------------- Iterator ---------------------
584  inline iterator begin() {
585  return _map.begin();
586  }
587 
588  inline const_iterator begin() const {
589  return _map.begin();
590  }
591 
592  inline iterator end() {
593  return _map.end();
594  }
595 
596  inline const_iterator end() const {
597  return _map.end();
598  }
599 
600  inline reverse_iterator rbegin() {
601  return _map.rbegin();
602  }
603 
604  inline const_reverse_iterator rbegin() const {
605  return _map.rbegin();
606  }
607 
608  inline reverse_iterator rend() {
609  return _map.rend();
610  }
611 
612  inline const_reverse_iterator rend() const {
613  return _map.rend();
614  }
615 
616  inline const_iterator cbegin() const {
617  return _map.cbegin();
618  }
619 
620  inline const_iterator cend() const {
621  return _map.cend();
622  }
623 
624  inline const_reverse_iterator crbegin() const {
625  return _map.crbegin();
626  }
627 
628  inline const_reverse_iterator crend() const {
629  return _map.crend();
630  }
631 
632  //--------------------- Capacity ---------------------
633  inline bool empty() const {
634  return _map.empty();
635  }
636 
637  inline size_type size() const {
638  return _map.size();
639  }
640 
641  inline size_type max_size() const {
642  return _map.max_size();
643  }
644 
645  //--------------------- Element access ---------------------
646  inline _Tp & operator[](_Key k) {
647  return _map[k];
648  }
649 
650  inline mapped_type& at (const key_type& k) {
651  return _map[k];
652  }
653 
654  inline const mapped_type& at (const key_type& k) const {
655  return _map[k];
656  }
657 
658  //--------------------- Operations ---------------------
659  inline iterator find (const key_type& k) {
660  std::lock_guard<std::recursive_mutex> lock(getMutex());
661  return _map.find(k);
662  }
663 
664  inline const_iterator find (const key_type& k) const {
665  std::lock_guard<std::recursive_mutex> lock(const_cast<EMMap<key_type, mapped_type>*>(this)->getMutex());
666  return _map.find(k);
667  }
668 
669  inline size_type count (const key_type& k) const {
670  std::lock_guard<std::recursive_mutex> lock(const_cast<EMMap<key_type, mapped_type>*>(this)->getMutex());
671  return _map.cout(k);
672  }
673 
674  inline iterator lower_bound (const key_type& k) {
675  std::lock_guard<std::recursive_mutex> lock(getMutex());
676  return _map.lower_bound(k);
677  }
678 
679  inline const_iterator lower_bound (const key_type& k) const {
680  std::lock_guard<std::recursive_mutex> lock(const_cast<EMMap<key_type, mapped_type>*>(this)->getMutex());
681  return _map.lower_bound(k);
682  }
683 
684  inline iterator upper_bound (const key_type& k) {
685  std::lock_guard<std::recursive_mutex> lock(getMutex());
686  return _map.upper_bound(k);
687  }
688 
689  inline const_iterator upper_bound (const key_type& k) const {
690  std::lock_guard<std::recursive_mutex> lock(const_cast<EMMap<key_type, mapped_type>*>(this)->getMutex());
691  return _map.upper_bound(k);
692  }
693 
694  inline std::pair<const_iterator,const_iterator> equal_range (const key_type& k) const {
695  std::lock_guard<std::recursive_mutex> lock(const_cast<EMMap<key_type, mapped_type>*>(this)->getMutex());
696  return _map.equal_range(k);
697  }
698 
699  inline std::pair<iterator,iterator> equal_range (const key_type& k) {
700  std::lock_guard<std::recursive_mutex> lock(getMutex());
701  return _map.equal_range(k);
702  }
703 
704  private:
705  std::map<_Key, _Tp> _map;
706  };
707 
708 
709  template <class _Key, class _Compare = std::less<_Key>,
710  class _Allocator = std::allocator<_Key> >
711  class EMSet : public EMSTLBase {
712  public:
713  typedef _Key key_type;
714  typedef key_type value_type;
715  typedef typename std::set<_Key>::iterator iterator;
716  typedef typename std::set<_Key>::const_iterator const_iterator;
717  typedef typename std::set<_Key>::reverse_iterator reverse_iterator;
718  typedef typename std::set<_Key>::const_reverse_iterator const_reverse_iterator;
719  typedef _Compare key_compare;
720  typedef key_compare value_compare;
721  typedef _Allocator allocator_type;
722  typedef typename std::set<_Key>::size_type size_type;
723 
724  explicit EMSet (const key_compare& comp = key_compare(),
725  const allocator_type& alloc = allocator_type()) {
726  std::set<key_type, key_compare, allocator_type> s = std::set<key_type, key_compare, allocator_type>
727  (comp, alloc);
728  }
729 
730  template <class InputIterator>
731  EMSet (InputIterator first, InputIterator last,
732  const key_compare& comp = key_compare(),
733  const allocator_type& alloc = allocator_type()) {
734  std::set<key_type, key_compare, allocator_type> s = std::set<key_type, key_compare, allocator_type>
735  (first, last, comp, alloc);
736  }
737 
738  inline EMSet & operator=(std::set<key_type> &set) {
739  _set = set;
740  return *this;
741  }
742 
743  virtual ~EMSet() {
744  }
745 
746  EMSet(const std::set<key_type> &v) {
747  _set = v;
748  }
749 
750  EMSet(const EMSet<key_type> &v) {
751  std::lock_guard<std::recursive_mutex> lock(const_cast<EMSet<key_type>&>(v).getMutex());
752  _set = v.get();
753  }
754 
755  inline EMSet & operator=(const EMSet<key_type> &v) {
756  if (this != &v) {
757  EMSet<key_type> *_v = const_cast<EMSet<key_type>*>(&v);
758  _lock_both(*this, *_v);
759  _set = v.get();
760  }
761  return *this;
762  }
763 
764  inline EMSet & operator=(const std::set<key_type> &v) {
765  std::lock_guard<std::recursive_mutex> lock(getMutex());
766  if (&_set != &v) {
767  _set = v;
768  }
769  return *this;
770  }
771 
772  EMSet(std::set<key_type> &v) {
773  _set = v;
774  }
775 
776  EMSet(EMSet<key_type> &v) {
777  _set = v.get();
778  }
779 
780 #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
781  EMSet(std::set<key_type> &&v) {
782  _set = std::move(v);
783  }
784 
785  EMSet(EMSet<key_type> &&v) {
786  std::lock_guard<std::recursive_mutex> lock(v.getMutex());
787  std::swap(_set, v._set);
788  v._set.clear();
789  }
790 
791  inline EMSet & operator=(EMSet<key_type> &&v) {
792  _lock_both(*this, v);
793  std::swap(_set, v._set);
794  v._vset.clear();
795  return *this;
796  }
797 
798  inline EMSet & operator=(std::set<key_type> &&v) {
799  std::lock_guard<std::recursive_mutex> lock(getMutex());
800  if (&_set != &v) {
801  _set = std::move(v);
802  }
803  return *this;
804  }
805 #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
806 
807  inline const std::set<key_type> & get() const {
808  return _set;
809  }
810 
811  inline std::set<key_type> clone() const {
812  EMSet<key_type> *temp = const_cast<EMSet<key_type> *>(this);
813  std::lock_guard<std::recursive_mutex> lock(temp->getMutex());
814  return _set;
815  }
816 
817 #ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
818  _LIBCPP_INLINE_VISIBILITY
819  EMSet(std::initializer_list<value_type> __il, const value_compare& __comp = value_compare())
820  {
821  _set = std::set<key_type>(__comp);
822  _set.insert(__il.begin(), __il.end());
823  }
824 
825  _LIBCPP_INLINE_VISIBILITY
826  EMSet(std::initializer_list<value_type> __il, const value_compare& __comp,
827  const allocator_type& __a)
828  {
829  _set = std::set<key_type>(__comp, __a);
830  _set.insert(__il.begin(), __il.end());
831  }
832 
833 #if _LIBCPP_STD_VER > 11
834  _LIBCPP_INLINE_VISIBILITY
835  EMSet(std::initializer_list<value_type> __il, const allocator_type& __a)
836  {
837  _set = std::set<key_type>(key_compare(), __a);
838  _set.insert(__il.begin(), __il.end());
839  }
840 #endif
841 
842  _LIBCPP_INLINE_VISIBILITY
843  inline EMSet& operator=(std::initializer_list<value_type> __il)
844  {
845  _set = std::set<key_type>();
846  _set.insert(__il.begin(), __il.end());
847  return *this;
848  }
849 #endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
850 
851  //--------------------- Modifiers ---------------------
852  inline std::pair<iterator,bool> insert (const value_type& val) {
853  std::lock_guard<std::recursive_mutex> lock(getMutex());
854  return _set.insert(val);
855  }
856 
857  inline iterator insert (iterator position, const value_type& val) {
858  std::lock_guard<std::recursive_mutex> lock(getMutex());
859  return _set.insert(position, val);
860  }
861 
862  template <class InputIterator>
863  inline void insert (InputIterator first, InputIterator last) {
864  std::lock_guard<std::recursive_mutex> lock(getMutex());
865  return _set.insert(first, last);
866  }
867 
868  // erase return type, http://cplusplush.com/map/map/erase/ definition is mismatched with gnustl/xcode code
869  inline iterator erase (iterator position) {
870  std::lock_guard<std::recursive_mutex> lock(getMutex());
871  return _set.erase(position);
872  }
873 
874  inline size_type erase (const value_type& val) {
875  std::lock_guard<std::recursive_mutex> lock(getMutex());
876  return _set.erase(val);
877  }
878 
879  inline iterator erase (iterator first, iterator last) {
880  std::lock_guard<std::recursive_mutex> lock(getMutex());
881  return _set.erase(first, last);
882  }
883 
884  inline void swap (std::set<key_type>& x) {
885  std::lock_guard<std::recursive_mutex> lock(getMutex());
886  _set.swap(x);
887  }
888 
889  inline void swap (EMSet<key_type>& x) {
890  _lock_both(*this, x);
891  _set.swap(x);
892  }
893 
894  inline void clear() {
895  std::lock_guard<std::recursive_mutex> lock(getMutex());
896  _set.clear();
897  }
898 
899  //--------------------- Iterators ---------------------
900  inline iterator begin() {
901  return _set.begin();
902  }
903 
904  inline const_iterator begin() const {
905  return _set.begin();
906  }
907 
908  inline iterator end() {
909  return _set.end();
910  }
911 
912  inline const_iterator end() const {
913  return _set.end();
914  }
915 
916  inline reverse_iterator rbegin() {
917  return _set.rbegin();
918  }
919 
920  inline const_reverse_iterator rbegin() const {
921  return _set.rbegin();
922  }
923 
924  inline reverse_iterator rend() {
925  return _set.rend();
926  }
927 
928  inline const_reverse_iterator rend() const {
929  return _set.rend();
930  }
931 
932  inline const_iterator cbegin() const {
933  return _set.cbegin();
934  }
935 
936  inline const_iterator cend() const {
937  return _set.cend();
938  }
939 
940  inline const_reverse_iterator crbegin() const {
941  return _set.crbegin();
942  }
943 
944  inline const_reverse_iterator crend() const {
945  return _set.crend();
946  }
947 
948  //--------------------- Capacity ---------------------
949  inline bool empty() const {
950  return _set.empty();
951  }
952 
953  inline size_type size() const {
954  return _set.size();
955  }
956 
957  inline size_type max_size() const {
958  return _set.max_size();
959  }
960 
961  //--------------------- Operations ---------------------
962  inline iterator find (const value_type& val) const {
963  std::lock_guard<std::recursive_mutex> lock(getMutex());
964  return _set.find(val);
965  }
966 
967  inline size_type count (const value_type& val) const {
968  std::lock_guard<std::recursive_mutex> lock(getMutex());
969  return _set.count(val);
970  }
971 
972  inline iterator lower_bound (const value_type& val) const {
973  std::lock_guard<std::recursive_mutex> lock(getMutex());
974  return _set.lower_bound(val);
975  }
976 
977  inline iterator upper_bound (const value_type& val) const {
978  std::lock_guard<std::recursive_mutex> lock(getMutex());
979  return _set.uppper_bound(val);
980  }
981 
982  inline std::pair<iterator,iterator> equal_range (const value_type& val) const {
983  std::lock_guard<std::recursive_mutex> lock(getMutex());
984  return _set.equal_range(val);
985  }
986 
987  private:
988  std::set<_Key> _set;
989  };
990 
991 }
992 
993 #endif /* emstl_h */
Definition: emstl.h:67
Definition: emstl.h:409
Definition: emattributevalue.h:28
Definition: emstl.h:711
Definition: emstl.h:102