5f4dfe8cf1
support.
221 lines
4.8 KiB
C++
221 lines
4.8 KiB
C++
|
|
/* wrapper for std::set */
|
|
|
|
template<class T>
|
|
class set : public set_wrapper<std::set<T>, T>
|
|
{
|
|
typedef set_wrapper<std::set<T>, T> base;
|
|
|
|
public:
|
|
set () { }
|
|
set (const set &m) : base(m) { }
|
|
set (copy, const set &m) : base(COPY, m) { }
|
|
set (initializer_list<T> il) : base(il) { }
|
|
set (reader &r) : base(r) { }
|
|
~set () { }
|
|
|
|
set &operator = (const set &m) { base::operator = (m); return *this; }
|
|
set &operator = (initializer_list<T> il) { base::operator = (il); }
|
|
|
|
bool operator == (const set &s) const;
|
|
bool operator != (const set &s) const { return !operator == (s); }
|
|
bool operator < (const set &s) const;
|
|
bool operator <= (const set &s) const;
|
|
|
|
bool toggle (const T &v);
|
|
|
|
set &operator |= (const set &s);
|
|
set &operator &= (const set &s);
|
|
set &operator ^= (const set &s);
|
|
};
|
|
|
|
template<class T>
|
|
using set_iter = set_wrapper_iter<std::set<T>, T>;
|
|
|
|
template<class T>
|
|
using set_const_iter = set_wrapper_const_iter<std::set<T>, T>;
|
|
|
|
template<class T> bool
|
|
set<T>::operator == (const set &s) const
|
|
{
|
|
typename std::set<T>::const_iterator i = this->impl->t.begin (),
|
|
j = s.impl->t.begin (),
|
|
iend = this->impl->t.end (),
|
|
jend = s.impl->t.end ();
|
|
|
|
while (i != iend && j != jend && *i == *j)
|
|
i ++, j ++;
|
|
|
|
return i == iend && j == jend;
|
|
}
|
|
|
|
template<class T> bool
|
|
set<T>::operator < (const set &s) const
|
|
{
|
|
typename std::set<T>::const_iterator i = this->impl->t.begin (),
|
|
j = s.impl->t.begin (),
|
|
iend = this->impl->t.end (),
|
|
jend = s.impl->t.end ();
|
|
|
|
while (i != iend && j != jend && *i == *j)
|
|
i ++, j ++;
|
|
|
|
return (i == iend && j != jend) || (i != iend && j != jend && *i < *j);
|
|
}
|
|
|
|
template<class T> bool
|
|
set<T>::operator <= (const set &s) const
|
|
{
|
|
typename std::set<T>::const_iterator i = this->impl->t.begin (),
|
|
j = s.impl->t.begin (),
|
|
iend = this->impl->t.end (),
|
|
jend = s.impl->t.end ();
|
|
|
|
while (i != iend && j != jend && *i == *j)
|
|
i ++, j ++;
|
|
|
|
return i == iend
|
|
|| (i != iend && j != jend && *i <= *j);
|
|
}
|
|
|
|
template<class T> bool
|
|
set<T>::toggle (const T &v)
|
|
{
|
|
typename std::set<T>::const_iterator i = this->impl->t.lower_bound (v),
|
|
end = this->impl->t.end ();
|
|
if (i != end && *i == v)
|
|
{
|
|
this->impl->t.erase (i);
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if (i == this->impl->t.begin ())
|
|
this->impl->t.insert (v);
|
|
else
|
|
{
|
|
typename std::set<T>::const_iterator j = --i;
|
|
assert (*j < v);
|
|
this->impl->t.insert (j, v);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
template<class T> set<T> &
|
|
set<T>::operator |= (const set &s)
|
|
{
|
|
std::set<T> news;
|
|
std::set_union (this->impl->t.begin (), this->impl->t.end (),
|
|
s.impl->t.begin (), s.impl->t.end (),
|
|
inserter (news, news.begin ()));
|
|
this->impl->t = news;
|
|
return *this;
|
|
}
|
|
|
|
template<class T> set<T> &
|
|
set<T>::operator &= (const set &s)
|
|
{
|
|
std::set<T> news;
|
|
std::set_intersection (this->impl->t.begin (), this->impl->t.end (),
|
|
s.impl->t.begin (), s.impl->t.end (),
|
|
inserter (news, news.begin ()));
|
|
this->impl->t = news;
|
|
return *this;
|
|
}
|
|
|
|
template<class T> set<T> &
|
|
set<T>::operator ^= (const set &s)
|
|
{
|
|
#if 0
|
|
printf ("before:\n");
|
|
printf ("this:");
|
|
for (typename std::set<T>::const_iterator i = this->impl->t.begin (); i != this->impl->t.end (); i ++)
|
|
printf (" %d", *i);
|
|
printf ("\n");
|
|
printf ("s:");
|
|
for (typename std::set<T>::const_iterator i = s.impl->t.begin (); i != s.impl->t.end (); i ++)
|
|
printf (" %d", *i);
|
|
printf ("\n");
|
|
#endif
|
|
|
|
#if 1
|
|
typename std::set<T>::const_iterator i = this->impl->t.begin (),
|
|
iend = this->impl->t.end (),
|
|
j = s.impl->t.begin (),
|
|
jend = s.impl->t.end ();
|
|
|
|
while (i != iend && j != jend && *i == *j)
|
|
{
|
|
this->impl->t.erase (i);
|
|
i = this->impl->t.begin ();
|
|
j ++;
|
|
}
|
|
|
|
if (i == iend)
|
|
this->impl->t.insert (j, jend);
|
|
else
|
|
{
|
|
if (j != jend && *j < *i)
|
|
{
|
|
i = this->impl->t.insert (*j).first;
|
|
j ++;
|
|
}
|
|
|
|
while (j != jend)
|
|
{
|
|
assert (*i < *j);
|
|
|
|
typename std::set<T>::const_iterator iprev = i ++;
|
|
if (i == iend)
|
|
{
|
|
while (j != jend)
|
|
{
|
|
iprev = this->impl->t.insert (iprev, *j);
|
|
j ++;
|
|
}
|
|
break;
|
|
}
|
|
else if (*i == *j)
|
|
{
|
|
this->impl->t.erase (i);
|
|
i = iprev;
|
|
j ++;
|
|
}
|
|
else
|
|
{
|
|
while (j != jend && *j < *i)
|
|
{
|
|
iprev = this->impl->t.insert (iprev, *j);
|
|
j ++;
|
|
}
|
|
if (j != jend && *j == *i)
|
|
{
|
|
this->impl->t.erase (i);
|
|
i = iprev;
|
|
j ++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
std::set<T> news;
|
|
std::set_symmetric_difference (this->impl->t.begin (), this->impl->t.end (),
|
|
s.impl->t.begin (), s.impl->t.end (),
|
|
inserter (news, news.begin ()));
|
|
this->impl->t = news;
|
|
#endif
|
|
|
|
#if 0
|
|
printf ("after:\n");
|
|
printf ("this:");
|
|
for (typename std::set<T>::const_iterator i = this->impl->t.begin (); i != this->impl->t.end (); i ++)
|
|
printf (" %d", *i);
|
|
printf ("\n");
|
|
#endif
|
|
|
|
return *this;
|
|
}
|