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)
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/unionfind.h lib/priority_queue.h lib/io.h \
lib/directed_multigraph.h

View File

@ -106,6 +106,7 @@ public:
polynomial &operator *= (polynomial p) { return operator = (*this * p); }
polynomial &operator *= (T s);
// ??? rename
polynomial &add_term (T c, unsigned 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 (const hashmap &m) : base(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 () { }
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>

View File

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

View File

@ -10,6 +10,7 @@
#include <gmp.h>
#include <zlib.h>
#include <initializer_list>
#include <set>
#include <map>
#include <string>
@ -167,6 +168,7 @@ using std::get;
using std::make_tuple;
using std::tie;
using std::ignore;
using std::initializer_list;
#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 (const map &m) : base(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 () { }
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>

View File

@ -15,6 +15,15 @@ class map_wrapper
{
public:
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;
@ -25,14 +34,24 @@ class map_wrapper
public:
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 (copy, const map_wrapper &m) : impl(new map_impl) { impl->t = M (m.impl->t); }
map_wrapper (copy2, const map_wrapper &m);
map_wrapper (copy, const map_wrapper &m) : impl(new map_impl (m.impl->t)) { }
map_wrapper (initializer_list<std::pair<const K, V> > il)
: impl(new map_impl (il))
{ }
map_wrapper (reader &r);
~map_wrapper () { }
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 */
pair<K, V> head () const
@ -136,15 +155,6 @@ class map_wrapper
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>
map_wrapper<M, K, V>::map_wrapper (reader &r)
: impl(new map_impl)

View File

@ -8,13 +8,14 @@ class set : public set_wrapper<std::set<T>, T>
public:
set () { }
set (unsigned dummy_size) : base(dummy_size) { }
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); }

View File

@ -15,6 +15,15 @@ class set_wrapper
{
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<T> il) : t(il) { }
~set_wrapper_impl () = default;
set_wrapper_impl &operator = (const set_wrapper_impl &) = delete;
};
ptr<set_wrapper_impl> impl;
@ -25,13 +34,25 @@ class set_wrapper
public:
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 (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 () { }
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 ()
{

View File

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

View File

@ -127,6 +127,47 @@ rank_lte (multivariate_laurentpoly<Z> p,
int
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);
v[1] = 2;
v[2] = -1;
@ -205,6 +246,7 @@ main ()
assert (sleb == sleb2);
assert (uleb == uleb2);
}
#endif
#if 0