#include #include #include "UnitTest++.h" #include "test_utils.hh" #include "geners/listIO.hh" #include "geners/arrayIO.hh" #include "geners/dequeIO.hh" #include "geners/setIO.hh" #include "geners/mapIO.hh" #include "geners/complexIO.hh" namespace haha { typedef struct {char a[2];} MyDummy; } gs_declare_type_as_pod(haha::MyDummy) gs_specialize_class_id(haha::MyDummy, 0) namespace { class Simple { public: inline Simple() : a_(0.0), b_(0) {} inline Simple(double a, int b) : a_(a), b_(b) {} inline double a() const {return a_;} inline int b() const {return b_;} inline bool operator==(const Simple& r) const {return a_ == r.a_ && b_ == r.b_;} inline bool operator!=(const Simple& r) const {return !(*this == r);} // Methods related to I/O follow inline gs::ClassId classId() const {return gs::ClassId(*this);} bool write(std::ostream& of) const; static inline const char* classname() {return "Simple";} static inline unsigned version() {return 1;} static void restore(const gs::ClassId& id, std::istream& in, Simple* objectPtr); private: double a_; int b_; }; bool Simple::write(std::ostream& of) const { gs::write_pod(of, a_); gs::write_pod(of, b_); return !of.fail(); } void Simple::restore(const gs::ClassId& id, std::istream& in, Simple* objectPtr) { static const gs::ClassId myId(gs::ClassId::makeId()); myId.ensureSameId(id); assert(objectPtr); gs::read_pod(in, &objectPtr->a_); gs::read_pod(in, &objectPtr->b_); if (in.fail()) throw gs::IOReadFailure(); } struct Order { inline bool operator()(const std::vector& v1, const std::vector& v2) { const unsigned sz1 = v1.size(); const unsigned sz2 = v2.size(); for (unsigned i=0; i proto; const int d = 234; int d2 = 0; CHECK(write_item(stream, d, true)); restore_item(stream, &d2, true); CHECK(d == d2); std::complex cmplx(3.0, 17.0), rcmplx(0.0, 0.0); write_pod(stream, cmplx); read_pod(stream, &rcmplx); CHECK(cmplx == rcmplx); rcmplx = std::complex(0.0, 0.0); CHECK(write_item(stream, cmplx, true)); restore_item(stream, &rcmplx, true); CHECK(cmplx == rcmplx); int intarr[3] = {3, 2, 1}, readarr[3] = {0,}; CHECK(write_array(stream, intarr, 3)); read_array(stream, readarr, 3); for (unsigned i=0; i<3; ++i) CHECK_EQUAL(intarr[i], readarr[i]); std::pair p1, p3; p1 = std::make_pair(23.0, Simple(45.0, -123)); CHECK(write_item(stream, p1, true)); restore_item(stream, &p3, true); CHECK(p1 == p3); std::basic_string s, sin = "hahahahswqdeq"; s += 13; s += 27; CHECK(write_item(stream, s, false)); restore_item(stream, &sin, false); CHECK(sin == s); CPP11_array,3> carr, r_carr; carr[0] = std::complex(1.f, 2.f); carr[1] = std::complex(17.f, 23.f); carr[2] = std::complex(234.f, -15.f); CHECK(write_item(stream, carr, true)); restore_item(stream, &r_carr, true); CHECK(carr == r_carr); CPP11_array arr, r_arr; for (unsigned i=0; i<15; ++i) arr[i] = i + 1.f; CHECK(write_item(stream, arr, true)); restore_item(stream, &r_arr, true); CHECK(r_arr == arr); Simple obj1(15.0, 777), obj2; CHECK(obj1.classId().write(stream) && obj1.write(stream)); ClassId simpleId(stream, 1); Simple::restore(simpleId, stream, &obj2); CHECK(obj1 == obj2); std::vector sarr(2); std::vector r_sarr; sarr[0] = Simple(23.0, 17); sarr[1] = Simple(-10.0, 3); CHECK(write_item(stream, sarr, true)); restore_item(stream, &r_sarr, true); CHECK(r_sarr == sarr); CPP11_array darr, r_darr; darr[0].a[0] = 'a'; darr[0].a[1] = 's'; darr[1].a[0] = 'd'; darr[1].a[1] = 'f'; r_darr[0].a[0] = 'h'; CHECK(write_item(stream, darr, true)); restore_item(stream, &r_darr, true); CHECK_EQUAL('a', r_darr[0].a[0]); CHECK_EQUAL('s', r_darr[0].a[1]); CHECK_EQUAL('d', r_darr[1].a[0]); CHECK_EQUAL('f', r_darr[1].a[1]); std::string haha = "crap", dudle = "dudle"; CHECK(write_item(stream, haha, true)); CHECK(write_item(stream, dudle, false)); std::string r_haha; restore_item(stream, &r_haha, true); CHECK(r_haha == haha); restore_item(stream, &r_haha, false); CHECK(r_haha == dudle); CPP11_array arrs; arrs[0] = haha; arrs[1] = dudle; process_const_item(arrs, stream, &proto, true); CPP11_array r_arrs; process_item(r_arrs, stream, &proto, true); CHECK(r_arrs == arrs); std::basic_string bs; bs += 10; bs += 20; process_const_item(bs, stream, &proto, true); std::basic_string rbs; process_item(rbs, stream, &proto, true); CHECK(rbs == bs); std::vector v1, v2; for (unsigned i=0; i<109; ++i) v1.push_back(static_cast(test_rng()*1000000)); process_const_item(v1, stream, &proto, true); process_item(v2, stream, &proto, true); CHECK(v1 == v2); std::list lst, lst2; lst.push_back(1); lst.push_back(2); lst.push_back(3); process_const_item(lst, stream, &proto, false); process_item(lst2, stream, &proto, false); CHECK(lst == lst2); std::deque dq, dq2; dq.push_back(4.0); dq.push_back(5.0); process_const_item(dq, stream, &proto, true); process_item(dq2, stream, &proto, true); CHECK(dq == dq2); std::multiset sf, sf2; sf.insert(2.f); sf.insert(4.f); sf.insert(4.f); sf.insert(3.f); process_const_item(sf, stream, &proto, true); process_item(sf2, stream, &proto, true); CHECK(sf == sf2); std::map mp, mp2; mp.insert(std::make_pair(1, 10.0)); mp.insert(std::make_pair(2, 15.0)); process_const_item(mp, stream, &proto, true); process_item(mp2, stream, &proto, true); CHECK(mp == mp2); std::vector vb, vb2; vb.push_back(1); vb.push_back(0); vb.push_back(1); process_const_item(vb, stream, &proto, true); process_item(vb2, stream, &proto, true); CHECK(vb == vb2); int ival = 34456, kval = 978645, jval = 0, lval = 32390, mval = 2579; process_const_item(ival, stream, &proto, true); process_const_item(kval, stream, &proto, true); process_const_item(lval, stream, &proto, true); process_const_item(mval, stream, &proto, true); int* iread = 0, *jread = &jval; process_item(iread, stream, &proto, true); CHECK(*iread == ival); process_item(jread, stream, &proto, true); CHECK(jval == kval); delete iread; CPP11_shared_ptr sptr(new int()); process_item(sptr, stream, &proto, true); CHECK(*sptr == lval); CPP11_shared_ptr sptr2; process_item(sptr2, stream, &proto, true); CHECK(*sptr2 == mval); std::vector vec1; for (unsigned i=0; i<10; ++i) vec1.push_back(new int(static_cast(test_rng()*1000000))); process_const_item(vec1, stream, &proto, true); std::vector vec3; CHECK(process_item(vec3, stream, &proto, true)); CHECK_EQUAL(10U, vec3.size()); for (unsigned i=0; i<10; ++i) { CHECK(*vec1[i] == *vec3[i]); delete vec3[i]; } std::vector > vec2; process_const_item(vec1, stream, &proto, true); CHECK(process_item(vec2, stream, &proto, true)); for (unsigned i=0; i<10; ++i) { CHECK(*vec1[i] == *vec2[i]); delete vec1[i]; } // Check that writing out an item by pointer is equivalent // to writing it out by reference -- up to a point. Writing // out the class id will be automatically turned on if the // item is written out by pointer. ival = 456; CHECK(write_item(stream, &ival, false)); CHECK(ival == 456); int ival_2 = 0; restore_item(stream, &ival_2, true); CHECK(ival == ival_2); // Check write_array/read_array for objects (non-PODs) const unsigned nsimple = 5; Simple simparr[nsimple]; for (unsigned i=0; i(test_rng()*100)); CHECK(write_array(stream, simparr, nsimple)); Simple simparr2[nsimple]; read_array(stream, simparr2, nsimple); for (unsigned i=0; i,double,Order> mp1; std::vector v1(2), v2(2); v1[0] = 1; v1[1] = 2; v2[0] = 1; v2[1] = 3; mp1[v1] = 2.0; mp1[v2] = 3.0; std::stringstream s; CHECK(write_item(s, mp1, true)); std::map,double,Order> mp2; restore_item(s, &mp2, true); CHECK(mp1 == mp2); } } }