More updates to c++11: partial initializer_lists and range-based for

support.
This commit is contained in:
Cotton Seed 2012-07-28 08:14:11 -04:00
parent fdb87caa41
commit 5f4dfe8cf1
11 changed files with 200 additions and 99 deletions

View File

@ -27,7 +27,8 @@ KNOTKIT_OBJS = planar_diagram.o dt_code.o knot_diagram.o cube.o spanning_tree_co
COMMON_OBJS = $(KNOTKIT_OBJS) $(ALGEBRA_OBJS) $(LIB_OBJS) COMMON_OBJS = $(KNOTKIT_OBJS) $(ALGEBRA_OBJS) $(LIB_OBJS)
LIB_HEADERS = lib/lib.h lib/show.h lib/refcount.h lib/pair.h lib/maybe.h lib/vector.h \ LIB_HEADERS = lib/lib.h lib/show.h lib/refcount.h lib/pair.h lib/maybe.h lib/vector.h \
lib/set.h lib/ullmanset.h lib/bitset.h lib/smallbitset.h lib/setcommon.h \ lib/set_wrapper.h lib/set.h lib/hashset.h \
lib/ullmanset.h lib/bitset.h lib/smallbitset.h lib/setcommon.h \
lib/map_wrapper.h lib/map.h lib/hashmap.h lib/ullmanmap.h lib/mapcommon.h \ lib/map_wrapper.h lib/map.h lib/hashmap.h lib/ullmanmap.h lib/mapcommon.h \
lib/unionfind.h lib/priority_queue.h lib/io.h \ lib/unionfind.h lib/priority_queue.h lib/io.h \
lib/directed_multigraph.h lib/directed_multigraph.h

View File

@ -106,6 +106,7 @@ public:
polynomial &operator *= (polynomial p) { return operator = (*this * p); } polynomial &operator *= (polynomial p) { return operator = (*this * p); }
polynomial &operator *= (T s); polynomial &operator *= (T s);
// ??? rename
polynomial &add_term (T c, unsigned e) polynomial &add_term (T c, unsigned e)
{ {
T &c2 = coeffs[e]; T &c2 = coeffs[e];

View File

@ -10,10 +10,16 @@ class hashmap : public map_wrapper<std::unordered_map<K, V, hasher<K> >, K, V>
hashmap () { } hashmap () { }
hashmap (const hashmap &m) : base(m) { } hashmap (const hashmap &m) : base(m) { }
hashmap (copy, const hashmap &m) : base(COPY, m) { } hashmap (copy, const hashmap &m) : base(COPY, m) { }
hashmap (initializer_list<std::pair<const K, V> > il) : base(il) { }
hashmap (reader &r) : base(r) { } hashmap (reader &r) : base(r) { }
~hashmap () { } ~hashmap () { }
hashmap &operator = (const hashmap &m) { base::operator = (m); return *this; } hashmap &operator = (const hashmap &m) { base::operator = (m); return *this; }
hashmap &operator = (initializer_list<std::pair<const K, V> > il)
{
base::operator = (il);
return *this;
}
}; };
template<class K, class V> template<class K, class V>

View File

@ -10,10 +10,12 @@ class hashset : public set_wrapper<std::unordered_set<T, hasher<T> >, T>
hashset () { } hashset () { }
hashset (const hashset &m) : base(m) { } hashset (const hashset &m) : base(m) { }
hashset (copy, const hashset &m) : base(COPY, m) { } hashset (copy, const hashset &m) : base(COPY, m) { }
hashset (initializer_list<T> il) : base(il) { }
hashset (reader &r) : base(r) { } hashset (reader &r) : base(r) { }
~hashset () { } ~hashset () { }
hashset &operator = (const hashset &m) { base::operator = (m); return *this; } hashset &operator = (const hashset &m) { base::operator = (m); return *this; }
hashset &operator = (initializer_list<T> il) { base::operator = (il); return *this; }
}; };
template<class T> template<class T>

View File

@ -10,6 +10,7 @@
#include <gmp.h> #include <gmp.h>
#include <zlib.h> #include <zlib.h>
#include <initializer_list>
#include <set> #include <set>
#include <map> #include <map>
#include <string> #include <string>
@ -167,6 +168,7 @@ using std::get;
using std::make_tuple; using std::make_tuple;
using std::tie; using std::tie;
using std::ignore; using std::ignore;
using std::initializer_list;
#include <lib/pair.h> #include <lib/pair.h>

View File

@ -11,11 +11,16 @@ class map : public map_wrapper<std::map<K, V>, K, V>
map (unsigned dummy_size) : base(dummy_size) { } map (unsigned dummy_size) : base(dummy_size) { }
map (const map &m) : base(m) { } map (const map &m) : base(m) { }
map (copy, const map &m) : base(COPY, m) { } map (copy, const map &m) : base(COPY, m) { }
map (copy2, const map &m) : base(COPY2, m) { } map (initializer_list<std::pair<const K, V> > il) : base(il) { }
map (reader &r) : base(r) { } map (reader &r) : base(r) { }
~map () { } ~map () { }
map &operator = (const map &m) { base::operator = (m); return *this; } map &operator = (const map &m) { base::operator = (m); return *this; }
map &operator = (initializer_list<std::pair<const K, V> > il)
{
base::operator = (il);
return *this;
}
}; };
template<class K, class V> template<class K, class V>

View File

@ -15,6 +15,15 @@ class map_wrapper
{ {
public: public:
M t; M t;
public:
map_impl () = default;
map_impl (const map_impl &) = delete;
map_impl (const M &t_) : t(t_) { }
map_impl (initializer_list<std::pair<const K, V> > il) : t(il) { }
~map_impl () = default;
map_impl &operator = (const map_impl &) = delete;
}; };
ptr<map_impl> impl; ptr<map_impl> impl;
@ -25,14 +34,24 @@ class map_wrapper
public: public:
map_wrapper () : impl(new map_impl) { } map_wrapper () : impl(new map_impl) { }
map_wrapper (unsigned dummy_size) : impl(new map_impl) { }
map_wrapper (const map_wrapper &m) : impl(m.impl) { } map_wrapper (const map_wrapper &m) : impl(m.impl) { }
map_wrapper (copy, const map_wrapper &m) : impl(new map_impl) { impl->t = M (m.impl->t); } map_wrapper (copy, const map_wrapper &m) : impl(new map_impl (m.impl->t)) { }
map_wrapper (copy2, const map_wrapper &m); map_wrapper (initializer_list<std::pair<const K, V> > il)
: impl(new map_impl (il))
{ }
map_wrapper (reader &r); map_wrapper (reader &r);
~map_wrapper () { } ~map_wrapper () { }
map_wrapper &operator = (const map_wrapper &m) { impl = m.impl; return *this; } map_wrapper &operator = (const map_wrapper &m) { impl = m.impl; return *this; }
map_wrapper &operator = (initializer_list<std::pair<const K, V> > il)
{
impl->t = il;
return *this;
}
// range-based for
typename M::const_iterator begin () const { return impl->t.begin (); }
typename M::const_iterator end () const { return impl->t.end (); }
/* returns the pair associated to the smallest key */ /* returns the pair associated to the smallest key */
pair<K, V> head () const pair<K, V> head () const
@ -136,15 +155,6 @@ class map_wrapper
void write_self (writer &w) const; void write_self (writer &w) const;
}; };
template<class M, class K, class V>
map_wrapper<M, K, V>::map_wrapper (copy2, const map_wrapper &m)
: impl(new map_impl)
{
/* Keys are immutable. Just copy the values. */
for (const_iter i = m; i; i ++)
push (i.key (), V (COPY, i.val ()));
}
template<class M, class K, class V> template<class M, class K, class V>
map_wrapper<M, K, V>::map_wrapper (reader &r) map_wrapper<M, K, V>::map_wrapper (reader &r)
: impl(new map_impl) : impl(new map_impl)

View File

@ -8,13 +8,14 @@ class set : public set_wrapper<std::set<T>, T>
public: public:
set () { } set () { }
set (unsigned dummy_size) : base(dummy_size) { }
set (const set &m) : base(m) { } set (const set &m) : base(m) { }
set (copy, const set &m) : base(COPY, m) { } set (copy, const set &m) : base(COPY, m) { }
set (initializer_list<T> il) : base(il) { }
set (reader &r) : base(r) { } set (reader &r) : base(r) { }
~set () { } ~set () { }
set &operator = (const set &m) { base::operator = (m); return *this; } 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;
bool operator != (const set &s) const { return !operator == (s); } bool operator != (const set &s) const { return !operator == (s); }

View File

@ -15,6 +15,15 @@ class set_wrapper
{ {
public: public:
S t; 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<T> il) : t(il) { }
~set_wrapper_impl () = default;
set_wrapper_impl &operator = (const set_wrapper_impl &) = delete;
}; };
ptr<set_wrapper_impl> impl; ptr<set_wrapper_impl> impl;
@ -25,13 +34,25 @@ class set_wrapper
public: public:
set_wrapper () : impl(new set_wrapper_impl) { } set_wrapper () : impl(new set_wrapper_impl) { }
set_wrapper (unsigned dummy_size) : impl(new set_wrapper_impl) { }
set_wrapper (const set_wrapper &s) : impl(s.impl) { } set_wrapper (const set_wrapper &s) : impl(s.impl) { }
set_wrapper (copy, const set_wrapper &s) : impl(new set_wrapper_impl) { impl->t = S (s.impl->t); } set_wrapper (copy, const set_wrapper &s)
: impl(new set_wrapper_impl (s.impl->t))
{ }
set_wrapper (initializer_list<T> il)
: impl(new set_wrapper_impl (il))
{ }
set_wrapper (reader &r); set_wrapper (reader &r);
~set_wrapper () { } ~set_wrapper () { }
set_wrapper &operator = (const set_wrapper &s) { impl = s.impl; return *this; } set_wrapper &operator = (const set_wrapper &s) { impl = s.impl; return *this; }
set_wrapper &operator = (initializer_list<T> 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 () T pop ()
{ {

View File

@ -2,12 +2,15 @@
template<unsigned B> class ullmanset_iter; template<unsigned B> class ullmanset_iter;
template<unsigned B> class ullmanset_const_iter; template<unsigned B> class ullmanset_const_iter;
template<unsigned B> class ullmanset_const_stl_iter;
template<unsigned B> template<unsigned B>
class ullmanset class ullmanset
{ {
private: private:
friend class ullmanset_iter<B>; friend class ullmanset_iter<B>;
friend class ullmanset_const_iter<B>; friend class ullmanset_const_iter<B>;
friend class ullmanset_const_stl_iter<B>;
class keypos class keypos
{ {
@ -16,57 +19,56 @@ class ullmanset
unsigned pos; unsigned pos;
}; };
class data class data : public refcounted
{ {
public: public:
unsigned refcount;
unsigned size; unsigned size;
unsigned n; unsigned n;
keypos kp[1]; keypos kp[1];
public:
inline void delete_at_pos (unsigned p);
}; };
data *d; ptr<data> d;
void ref (data *newd) { assert (!d); d = newd; if (d) d->refcount ++; }
void unref ();
inline void delete_at_pos (unsigned p);
public: public:
typedef ullmanset_iter<B> iter; typedef ullmanset_iter<B> iter;
typedef ullmanset_const_iter<B> const_iter; typedef ullmanset_const_iter<B> const_iter;
public: public:
ullmanset () : d(0) { }
ullmanset (unsigned size); ullmanset (unsigned size);
ullmanset (const ullmanset &s) : d(0) { ref (s.d); } ullmanset () : ullmanset(0) { }
ullmanset (const ullmanset &s) : d(s.d) { }
ullmanset (copy, const ullmanset &s); ullmanset (copy, const ullmanset &s);
// ullmanset (const unsignedset &t);
ullmanset (const bitset &t); ullmanset (const bitset &t);
ullmanset (unsigned size, initializer_list<unsigned> il);
ullmanset (reader &r); ullmanset (reader &r);
~ullmanset () { unref (); } ~ullmanset () { }
ullmanset &operator = (const ullmanset &s) { unref (); ref (s.d); return *this; } ullmanset &operator = (const ullmanset &s) { d = s.d; return *this; }
// ullmanset &operator = (const unsignedset &t);
ullmanset &operator = (const bitset &t); ullmanset &operator = (const bitset &t);
unsigned size () const { return d ? d->size : 0; } // range-based for
inline ullmanset_const_stl_iter<B> begin () const;
inline ullmanset_const_stl_iter<B> end () const;
bool is_empty () const { assert (d); return d->n == 0; } unsigned size () const { return d->size; }
unsigned card () const { assert (d); return d->n; }
unsigned head () const { assert (d); assert (d->n > 0); return d->kp[0].key; } bool is_empty () const { return d->n == 0; }
unsigned card () const { return d->n; }
unsigned head () const { assert (d->n > 0); return d->kp[0].key; }
bool operator == (const ullmanset &s); bool operator == (const ullmanset &s);
bool operator != (const ullmanset &s) { return !operator == (s); } bool operator != (const ullmanset &s) { return !operator == (s); }
void restore (unsigned old_card) void restore (unsigned old_card)
{ {
assert (d);
assert (d->n >= old_card); assert (d->n >= old_card);
d->n = old_card; d->n = old_card;
} }
void clear () { if (d) { d->n = 0; } } void clear () { d->n = 0; }
inline void push (unsigned k); inline void push (unsigned k);
inline void operator += (unsigned k); // ??? should these be inline? inline void operator += (unsigned k); // ??? should these be inline?
@ -88,89 +90,75 @@ class ullmanset
bool operator % (unsigned k) const bool operator % (unsigned k) const
{ {
assert (d);
assert ((k - B) >= 0); assert ((k - B) >= 0);
assert ((k - B) < d->size); assert ((k - B) < d->size);
unsigned p = d->kp[k - B].pos; unsigned p = d->kp[k - B].pos;
return p < d->n && d->kp[p].key == k; return p < d->n && d->kp[p].key == k;
} }
bool operator () (unsigned k) const { return operator % (k); } bool operator () (unsigned k) const { return operator % (k); }
// always 0-based // always 0-based
unsigned nth (unsigned p) const { assert (d); assert (p < d->n); return d->kp[p].key; } unsigned nth (unsigned p) const
{
assert (p < d->n);
return d->kp[p].key;
}
unsigned position (unsigned k) const { assert (operator % (k)); return d->kp[k - B].pos; } unsigned position (unsigned k) const
{
assert (operator % (k));
return d->kp[k - B].pos;
}
void write_self (writer &w) const; void write_self (writer &w) const;
}; };
template<unsigned B> void template<unsigned B> void
ullmanset<B>::unref () ullmanset<B>::data::delete_at_pos (unsigned p)
{ {
if (d && --d->refcount == 0) assert (p < n);
{ --n;
delete [] (char *)d;
d = 0;
}
}
template<unsigned B> void
ullmanset<B>::delete_at_pos (unsigned p)
{
assert (d);
assert (p < d->n);
unsigned n = --d->n;
if (p != n) if (p != n)
{ {
unsigned ell = d->kp[n].key; unsigned ell = kp[n].key;
d->kp[ell - B].pos = p; kp[ell - B].pos = p;
d->kp[p].key = ell; kp[p].key = ell;
} }
} }
template<unsigned B> template<unsigned B>
ullmanset<B>::ullmanset (unsigned size) ullmanset<B>::ullmanset (unsigned size)
: d(0)
{ {
data *newd = (data *)new char[sizeof (data) data *newd = (data *)new char[sizeof (data)
+ sizeof (keypos) * size + sizeof (keypos) * size
- sizeof (keypos)]; - sizeof (keypos)];
newd->refcount = 0; new (newd) data;
newd->size = size; newd->size = size;
newd->n = 0; newd->n = 0;
ref (newd); d = newd;
}
template<unsigned B>
ullmanset<B>::ullmanset (unsigned size, initializer_list<unsigned> il)
: ullmanset(size)
{
for (unsigned i : il)
operator += (i);
} }
template<unsigned B> template<unsigned B>
ullmanset<B>::ullmanset (copy, const ullmanset &s) ullmanset<B>::ullmanset (copy, const ullmanset &s)
: d(0) : ullmanset(s.size ())
{ {
if (s.d) d->n = s.d->n;
{ memcpy (&d->kp[0], &s.d->kp[0], sizeof (keypos) * d->n);
unsigned bytes = (sizeof (data)
+ sizeof (keypos) * s.d->size
- sizeof (keypos));
data *newd = (data *)new char[bytes];
memcpy (newd, s.d, bytes);
newd->refcount = 0;
ref (newd);
}
} }
template<unsigned B> template<unsigned B>
ullmanset<B>::ullmanset (reader &r) ullmanset<B>::ullmanset (reader &r)
: d(0) : ullmanset(r.read_unsigned ())
{ {
unsigned size_ = r.read_unsigned ();
if (size_ > 0)
{
data *newd = (data *)new char[sizeof (data) + sizeof (keypos) * (size_ - 1)];
newd->refcount = 0;
newd->size = size_;
newd->n = 0;
ref (newd);
}
unsigned card_ = r.read_unsigned (); unsigned card_ = r.read_unsigned ();
for (unsigned i = 0; i < card_; i ++) for (unsigned i = 0; i < card_; i ++)
push (r.read_unsigned ()); push (r.read_unsigned ());
@ -179,8 +167,6 @@ ullmanset<B>::ullmanset (reader &r)
template<unsigned B> bool template<unsigned B> bool
ullmanset<B>::operator == (const ullmanset &s) ullmanset<B>::operator == (const ullmanset &s)
{ {
assert (d);
assert (s.d);
if (d->n != s.d->n) if (d->n != s.d->n)
return 0; return 0;
for (iter i = *this; i; i ++) for (iter i = *this; i; i ++)
@ -194,7 +180,6 @@ ullmanset<B>::operator == (const ullmanset &s)
template<unsigned B> void template<unsigned B> void
ullmanset<B>::push (unsigned k) ullmanset<B>::push (unsigned k)
{ {
assert (d);
assert (!operator % (k)); assert (!operator % (k));
unsigned p = d->n ++; unsigned p = d->n ++;
d->kp[p].key = k; d->kp[p].key = k;
@ -204,7 +189,6 @@ ullmanset<B>::push (unsigned k)
template<unsigned B> void template<unsigned B> void
ullmanset<B>::operator += (unsigned k) ullmanset<B>::operator += (unsigned k)
{ {
assert (d);
assert ((k - B) >= 0); assert ((k - B) >= 0);
assert ((k - B) < d->size); assert ((k - B) < d->size);
if (!operator % (k)) if (!operator % (k))
@ -218,13 +202,12 @@ ullmanset<B>::operator += (unsigned k)
template<unsigned B> void template<unsigned B> void
ullmanset<B>::operator -= (unsigned k) ullmanset<B>::operator -= (unsigned k)
{ {
assert (d);
assert ((k - B) >= 0); assert ((k - B) >= 0);
assert ((k - B) < d->size); assert ((k - B) < d->size);
if (operator % (k)) if (operator % (k))
{ {
unsigned p = d->kp[k - B].pos; unsigned p = d->kp[k - B].pos;
delete_at_pos (p); d->delete_at_pos (p);
} }
} }
@ -270,22 +253,49 @@ ullmanset<B>::write_self (writer &w) const
write (w, i.val ()); write (w, i.val ());
} }
template<unsigned B>
class ullmanset_const_stl_iter
{
private:
ptr<typename ullmanset<B>::data> d;
unsigned p;
public:
ullmanset_const_stl_iter (const ullmanset<B> &s, unsigned p_) : d(s.d), p(p_) { }
bool operator != (const ullmanset_const_stl_iter &end) const { return p != end.p; }
unsigned operator * () const { assert (p < d->n); return d->kp[p].key; }
ullmanset_const_stl_iter &operator ++ () { p ++; return *this; }
};
template<unsigned B> ullmanset_const_stl_iter<B>
ullmanset<B>::begin () const
{
return ullmanset_const_stl_iter<B> (*this, 0);
}
template<unsigned B> ullmanset_const_stl_iter<B>
ullmanset<B>::end () const
{
return ullmanset_const_stl_iter<B> (*this, d->n);
}
template<unsigned B> template<unsigned B>
class ullmanset_iter class ullmanset_iter
{ {
private: private:
ullmanset<B> &s; ptr<typename ullmanset<B>::data> d;
unsigned i; unsigned i;
bool deleted; bool deleted;
public: public:
ullmanset_iter (ullmanset<B> &s_) : s(s_), i(0), deleted(0) { assert (s_.d); } ullmanset_iter (ullmanset<B> &s) : d(s.d), i(0), deleted(0) { }
~ullmanset_iter () { } ~ullmanset_iter () { }
void del () { assert (!deleted); assert (i < s.d->n); s.delete_at_pos (i); } void del () { assert (!deleted); assert (i < d->n); d->delete_at_pos (i); }
unsigned val () const { assert (!deleted); assert (i < s.d->n); return s.d->kp[i].key; } unsigned val () const { assert (!deleted); assert (i < d->n); return d->kp[i].key; }
unsigned pos () const { assert (!deleted); assert (i < s.d->n); return i; } unsigned pos () const { assert (!deleted); assert (i < d->n); return i; }
operator bool () const { assert (!deleted); return i < s.d->n; } operator bool () const { assert (!deleted); return i < d->n; }
void operator ++ () { if (deleted) deleted = 0; else i ++; } void operator ++ () { if (deleted) deleted = 0; else i ++; }
void operator ++ (int) { operator ++ (); } void operator ++ (int) { operator ++ (); }
}; };
@ -294,16 +304,16 @@ template<unsigned B>
class ullmanset_const_iter class ullmanset_const_iter
{ {
private: private:
const ullmanset<B> &s; ptr<typename ullmanset<B>::data> d;
unsigned i; unsigned i;
public: public:
ullmanset_const_iter (const ullmanset<B> &s_) : s(s_), i(0) { assert (s_.d); } ullmanset_const_iter (const ullmanset<B> &s) : d(s.d), i(0) { }
~ullmanset_const_iter () { } ~ullmanset_const_iter () { }
unsigned val () const { assert (i < s.d->n); return s.d->kp[i].key; } unsigned val () const { assert (i < d->n); return d->kp[i].key; }
unsigned pos () const { assert (i < s.d->n); return i; } unsigned pos () const { assert (i < d->n); return i; }
operator bool () const { return i < s.d->n; } operator bool () const { return i < d->n; }
void operator ++ () { i ++; } void operator ++ () { i ++; }
void operator ++ (int) { i ++; } void operator ++ (int) { i ++; }
}; };

View File

@ -127,6 +127,47 @@ rank_lte (multivariate_laurentpoly<Z> p,
int int
main () main ()
{ {
#if 0
ullmanset<1> empty;
assert (empty.size () == 0);
assert (empty.card () == 0);
assert (empty.is_empty ());
ullmanset<1> empty2;
assert (empty == empty2);
ullmanset<1> emptycopy (COPY, empty);
assert (emptycopy == empty);
ullmanset<1> s (50, {1,2,5,5,2,1,3,4});
assert (s.card () == 5);
ullmanset<1> scopy (COPY, s);
assert (scopy == s);
printf ("s:");
for (int x : s)
printf (" %d", x);
newline ();
#endif
map<unsigned, const char *> m = { { 5, "foo" }, { 11, "bar" } };
hashmap<unsigned, const char *> m2 = { { 5, "foo" }, { 11, "bar" }, { 37, "baz" } };
for (std::pair<unsigned, const char *> i : m2)
{
printf ("%d -> %s\n", i.first, i.second);
}
#if 0
set<unsigned> s {1,2,5,5,2,1,3,4};
printf ("s:");
for (int x : s)
printf (" %d", x);
newline ();
#endif
#if 0
basedvector<int, 1> v (4); basedvector<int, 1> v (4);
v[1] = 2; v[1] = 2;
v[2] = -1; v[2] = -1;
@ -205,6 +246,7 @@ main ()
assert (sleb == sleb2); assert (sleb == sleb2);
assert (uleb == uleb2); assert (uleb == uleb2);
} }
#endif
#if 0 #if 0