/* wrapper for STL maps */ template class set_wrapper_iter; template class set_wrapper_const_iter; template class set_wrapper { friend class set_wrapper_iter; friend class set_wrapper_const_iter; protected: class set_wrapper_impl : public refcounted { public: S t; public: set_wrapper_impl () = default; set_wrapper_impl (const set_wrapper_impl &) = delete; set_wrapper_impl (const S &t_) : t(t_) { } set_wrapper_impl (initializer_list il) : t(il) { } ~set_wrapper_impl () = default; set_wrapper_impl &operator = (const set_wrapper_impl &) = delete; }; ptr impl; public: typedef set_wrapper_iter iter; typedef set_wrapper_const_iter const_iter; public: set_wrapper () : impl(new set_wrapper_impl) { } set_wrapper (const set_wrapper &s) : impl(s.impl) { } set_wrapper (copy, const set_wrapper &s) : impl(new set_wrapper_impl (s.impl->t)) { } set_wrapper (initializer_list il) : impl(new set_wrapper_impl (il)) { } set_wrapper (reader &r); ~set_wrapper () { } set_wrapper &operator = (const set_wrapper &s) { impl = s.impl; return *this; } set_wrapper &operator = (initializer_list li) { impl->t = li; } // range-based for typename S::const_iterator begin () const { return impl->t.begin (); } typename S::const_iterator end () const { return impl->t.end (); } T pop () { typename S::const_iterator i = impl->t.begin (); assert (i != impl->t.end ()); T tmp = *i; impl->t.erase (i); return tmp; } bool is_empty () const { return impl->t.empty (); } unsigned card () const { return impl->t.size (); } const T &head () const; const T &tail () const; void clear () { impl->t.clear (); } void push (const T &v) { assert (impl->t.find (v) == impl->t.end ()); impl->t.insert (v); } void operator += (const T &v) { impl->t.insert (v); } void operator -= (const T &v) { impl->t.erase (v); } void yank (const T &v) { assert (operator % (v)); impl->t.erase (v); } bool operator % (const T &v) const { return impl->t.find (v) != impl->t.end (); } bool operator () (const T &v) const { return operator % (v); } void write_self (writer &w) const; hash_t hash_self () const; }; template class set_wrapper_iter { ptr::set_wrapper_impl> impl; typename S::const_iterator i, end; bool deleted; public: set_wrapper_iter (set_wrapper &s) : impl(s.impl), i(s.impl->t.begin ()), end(s.impl->t.end ()), deleted(0) { } ~set_wrapper_iter () { } void del () { assert (!deleted); typename S::const_iterator iprev = i ++; impl->t.erase (iprev); deleted = 1; } const T &val () const { assert (!deleted); return *i; } operator bool () const { assert (!deleted); return i != end; } set_wrapper_iter &operator ++ () { if (deleted) deleted = 0; else i ++; return *this; } void operator ++ (int) { operator ++ (); } }; template class set_wrapper_const_iter { ptr::set_wrapper_impl> impl; typename S::const_iterator i, end; public: set_wrapper_const_iter (const set_wrapper &s) : impl(s.impl), i(s.impl->t.begin ()), end(s.impl->t.end ()) { } ~set_wrapper_const_iter () { } const T &val () const { return *i; } operator bool () const { return i != end; } set_wrapper_const_iter &operator ++ () { i ++; return *this; } void operator ++ (int) { i ++; } }; template set_wrapper::set_wrapper (reader &r) : impl(new set_wrapper_impl) { unsigned n; read (r, n); T x; for (unsigned i = 0; i < n; i ++) { read (r, x); push (x); } } template const T & set_wrapper::head () const { set_wrapper_const_iter i = *this; assert (i); return i.val (); } template const T & set_wrapper::tail () const { typename S::const_reverse_iterator i = impl->t.rbegin (); assert (i != impl->t.rend ()); return *i; } template void set_wrapper::write_self (writer &w) const { write (w, card ()); for (const_iter i = *this; i; i ++) write (w, i.val ()); } template hash_t set_wrapper::hash_self () const { hash_t h = hash (card ()); unsigned j = 0; for (const_iter i = *this; i && j < 10; i ++, j ++) h = hash_combine (h, hash (i.val ())); return h; }