diff --git a/algebra/Z2.h b/algebra/Z2.h index ea4514b..f13f192 100644 --- a/algebra/Z2.h +++ b/algebra/Z2.h @@ -13,6 +13,7 @@ class Z2 Z2 (int x) : v((bool)(x & 1)) { } Z2 (bool v_) : v(v_) { } Z2 (const Z2 &x) : v(x.v) { } + Z2 (copy, const Z2 &x) : v(x.v) { } ~Z2 () { } Z2 &operator = (const Z2 &x) { v = x.v; return *this; } diff --git a/algebra/multivariate_laurentpoly.h b/algebra/multivariate_laurentpoly.h index cf4df00..49c2137 100644 --- a/algebra/multivariate_laurentpoly.h +++ b/algebra/multivariate_laurentpoly.h @@ -56,15 +56,6 @@ class multivariate_laurent_monomial return m == e.m; } - bool operator < (const multivariate_laurent_monomial &e) const - { -#ifndef NDEBUG - check (); - e.check (); -#endif - return m < e.m; - } - bool operator == (int x) const { assert (x == 1); @@ -76,6 +67,24 @@ class multivariate_laurent_monomial bool operator != (int x) const { return !operator == (x); } + bool operator < (const multivariate_laurent_monomial &e) const + { +#ifndef NDEBUG + check (); + e.check (); +#endif + return m < e.m; + } + + bool operator <= (const multivariate_laurent_monomial &e) const + { +#ifndef NDEBUG + check (); + e.check (); +#endif + return m <= e.m; + } + multivariate_laurent_monomial &operator *= (const multivariate_laurent_monomial &e) { for (map::const_iter i = e.m; i; i ++) @@ -203,7 +212,7 @@ class multivariate_laurentpoly multivariate_laurentpoly (const multivariate_laurentpoly &p) : coeffs(p.coeffs) { } multivariate_laurentpoly (copy, const multivariate_laurentpoly &p) - : coeffs(COPY, p.coeffs) + : coeffs(COPY2, p.coeffs) { } @@ -226,7 +235,7 @@ class multivariate_laurentpoly return *this; } - bool operator == (multivariate_laurentpoly p) const + bool operator == (const multivariate_laurentpoly &p) const { #ifndef NDEBUG check (); @@ -235,9 +244,6 @@ class multivariate_laurentpoly return coeffs == p.coeffs; } - unsigned card () const { return coeffs.card (); } - pair head () const { return coeffs.head (); } - bool operator == (int x) const { #ifndef NDEBUG @@ -259,9 +265,30 @@ class multivariate_laurentpoly bool operator != (int x) const { return !operator == (x); } - multivariate_laurentpoly &operator += (multivariate_laurentpoly p); - multivariate_laurentpoly &operator -= (multivariate_laurentpoly p); - multivariate_laurentpoly &operator *= (multivariate_laurentpoly p) + bool operator < (const multivariate_laurentpoly &p) const + { +#ifndef NDEBUG + check (); + p.check (); +#endif + return coeffs < p.coeffs; + } + + bool operator <= (const multivariate_laurentpoly &p) const + { +#ifndef NDEBUG + check (); + p.check (); +#endif + return coeffs <= p.coeffs; + } + + unsigned card () const { return coeffs.card (); } + pair head () const { return coeffs.head (); } + + multivariate_laurentpoly &operator += (const multivariate_laurentpoly &p); + multivariate_laurentpoly &operator -= (const multivariate_laurentpoly &p); + multivariate_laurentpoly &operator *= (const multivariate_laurentpoly &p) { return operator = (*this * p); } @@ -290,14 +317,14 @@ class multivariate_laurentpoly multivariate_laurentpoly &muladdeq (multivariate_laurentpoly a, multivariate_laurentpoly b); multivariate_laurentpoly operator - () const { return multivariate_laurentpoly () - *this; } - multivariate_laurentpoly operator + (multivariate_laurentpoly p) const + multivariate_laurentpoly operator + (const multivariate_laurentpoly &p) const { multivariate_laurentpoly r (COPY, *this); r += p; return r; } - multivariate_laurentpoly operator - (multivariate_laurentpoly p) const + multivariate_laurentpoly operator - (const multivariate_laurentpoly &p) const { multivariate_laurentpoly r (COPY, *this); r -= p; @@ -330,7 +357,7 @@ operator * (const T &s, const multivariate_laurentpoly &p) } template multivariate_laurentpoly & -multivariate_laurentpoly::operator += (multivariate_laurentpoly p) +multivariate_laurentpoly::operator += (const multivariate_laurentpoly &p) { for (typename map::const_iter i = p.coeffs; i; i ++) { @@ -344,7 +371,7 @@ multivariate_laurentpoly::operator += (multivariate_laurentpoly p) } template multivariate_laurentpoly & -multivariate_laurentpoly::operator -= (multivariate_laurentpoly p) +multivariate_laurentpoly::operator -= (const multivariate_laurentpoly &p) { for (typename map::const_iter i = p.coeffs; i; i ++) { diff --git a/lib/io.cpp b/lib/io.cpp index c900a73..a02ccd0 100644 --- a/lib/io.cpp +++ b/lib/io.cpp @@ -157,3 +157,33 @@ reader::read_uint64 () } return x; } + +void +read (reader &r, std::string &s) +{ + unsigned n = r.read_unsigned (); + + char buf[n + 1]; + unsigned k = fread (buf, sizeof (char), n + 1, r.fp); + if (k != n + 1) + { + stderror ("fread"); + exit (EXIT_FAILURE); + } + assert (buf[n] == 0); + + s = std::string (buf); +} + +void +write (writer &w, const std::string &s) +{ + unsigned n = s.length (); + w.write_unsigned (n); + + if (fwrite (s.c_str (), sizeof (char), n + 1, w.fp) != n + 1) + { + stderror ("fwrite"); + exit (EXIT_FAILURE); + } +} diff --git a/lib/io.h b/lib/io.h index 5ce6f9c..9f499e9 100644 --- a/lib/io.h +++ b/lib/io.h @@ -45,6 +45,7 @@ inline void read (reader &r, char &x) { x = r.read_char (); } inline void read (reader &r, int &x) { x = r.read_int (); } inline void read (reader &r, unsigned &x) { x = r.read_unsigned (); } inline void read (reader &r, uint64 &x) { x = r.read_uint64 (); } +void read (reader &r, std::string &s); template inline void read (reader &r, T &x) { x = T(r); } inline void ctor_read (reader &r, bool *p) { *p = r.read_bool (); } @@ -59,4 +60,5 @@ inline void write (writer &w, char x) { w.write_char (x); } inline void write (writer &w, int x) { w.write_int (x); } inline void write (writer &w, unsigned x) { w.write_unsigned (x); } inline void write (writer &w, uint64 x) { w.write_uint64 (x); } +void write (writer &w, const std::string &s); template inline void write (writer &w, const T &x) { x.write_self (w); } diff --git a/lib/map.h b/lib/map.h index cb3ea78..3be8881 100644 --- a/lib/map.h +++ b/lib/map.h @@ -11,6 +11,7 @@ class map : public map_wrapper, 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 (reader &r) : base(r) { } ~map () { } diff --git a/lib/map_wrapper.h b/lib/map_wrapper.h index 8aae708..762bfc7 100644 --- a/lib/map_wrapper.h +++ b/lib/map_wrapper.h @@ -28,6 +28,7 @@ class map_wrapper 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 (reader &r); ~map_wrapper () { } @@ -134,6 +135,15 @@ class map_wrapper void write_self (writer &w) const; }; +template +map_wrapper::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 map_wrapper::map_wrapper (reader &r) : impl(new map_impl) diff --git a/main.cpp b/main.cpp index 5c7a627..074fc13 100644 --- a/main.cpp +++ b/main.cpp @@ -143,23 +143,50 @@ main () } #endif - map m; - m.push ("foo", 3); - m.push ("barz", 4); - m.push ("pazazz", 39); + multivariate_laurentpoly p = -11; + p.muladdeq (5, VARIABLE, 1); + p.muladdeq (7, VARIABLE, 2); + p.muladdeq (-3, VARIABLE, 3); + + multivariate_laurentpoly q = p*p + p + 23; + multivariate_laurentpoly r = q*q - Z (7)*p + 81; - assert (m % "foo"); - assert (m("foo") == 3); - assert (! (m % "fop")); + multivariate_laurentpoly s = r - p*q + 10; + + display ("p:", p); + display ("q:", q); + display ("r:", r); + display ("s:", s); - hashmap m2; - m2.push ("foo", 3); - m2.push ("barz", 4); - m2.push ("pazazz", 39); + map, std::string> m; + m.push (p, "p"); + m.push (q, "q"); + m.push (r, "thisisr"); - assert (m2 % "foo"); - assert (m2("foo") == 3); - assert (! (m2 % "fop")); + assert (m % p); + assert (m % q); + assert (m % r); + assert (! (m % s)); + + assert (m(p) == "p"); + assert (m(q) == "q"); + assert (m(r) == "thisisr"); + + std::string str ("This is a test."); + + { + writer w ("test.dat"); + write (w, m); + } + + reader rdr ("test.dat"); + map, std::string> m2 (rdr); + + assert (m == m2); + + assert (m2(p) == "p"); + assert (m2(q) == "q"); + assert (m2(r) == "thisisr"); #if 0 test_ring (2); diff --git a/todo.txt b/todo.txt index f043efd..ad38695 100644 --- a/todo.txt +++ b/todo.txt @@ -9,6 +9,8 @@ in knotkit/ - unify chain_complex_simplifer and build_sseq - remove hardcoded limits (max_...) - revive testlib + - figure out proper copy interface and consistently support copy and + deepcopy in lib/ - add hashset