From bceb06251cdb572850b2e6e4d15cfb2ac32da417 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 19 Oct 2011 10:47:41 +0200 Subject: Add support for const data members Const data members are automatically treated as readonly. New test: const-member. --- common/readonly/driver.cxx | 67 +++++++++++++++++++++++++++++++++++++++++++--- common/readonly/test.hxx | 56 +++++++++++++++++++++++++++++++------- 2 files changed, 110 insertions(+), 13 deletions(-) (limited to 'common/readonly') diff --git a/common/readonly/driver.cxx b/common/readonly/driver.cxx index 2ad40a1..0432c69 100644 --- a/common/readonly/driver.cxx +++ b/common/readonly/driver.cxx @@ -3,7 +3,9 @@ // copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC // license : GNU GPL v2; see accompanying LICENSE file -// Test readonly members/objects. +// Test readonly members/objects. Also test that const members are +// treated as readonly. For other const member tests, see the const- +// member test. // #include // std::auto_ptr @@ -40,7 +42,7 @@ main (int argc, char* argv[]) } o.ro++; - // const_cast (o.co)++; + const_cast (o.co)++; o.rw++; { @@ -55,7 +57,7 @@ main (int argc, char* argv[]) t.commit (); } - assert (o.ro == 1 && /*o.co == 1 &&*/ o.rw == 2); + assert (o.ro == 1 && o.co == 1 && o.rw == 2); } // Pointer. @@ -74,6 +76,7 @@ main (int argc, char* argv[]) delete p.ro; p.ro = p1.release (); + const_cast (p.co) = p.ro; p.rw = p.ro; { @@ -87,7 +90,7 @@ main (int argc, char* argv[]) auto_ptr p (db->load (1)); t.commit (); - assert (p->ro->id == 2 && p->rw->id == 3); + assert (p->ro->id == 2 && p->co->id == 2 && p->rw->id == 3); } } @@ -104,10 +107,18 @@ main (int argc, char* argv[]) o.ro.v++; o.ro.ro++; + const_cast (o.ro.co)++; o.ro.rw++; + value& co (const_cast (o.co)); + co.v++; + co.ro++; + const_cast (co.co)++; + co.rw++; + o.rw.v++; o.rw.ro++; + const_cast (o.rw.co)++; o.rw.rw++; o.v.v++; @@ -126,10 +137,17 @@ main (int argc, char* argv[]) assert (o.ro.v == 1 && o.ro.ro == 1 && + o.ro.co == 1 && o.ro.rw == 1 && + o.co.v == 1 && + o.co.ro == 1 && + o.co.co == 1 && + o.co.rw == 1 && + o.rw.v == 1 && o.rw.ro == 1 && + o.rw.co == 1 && o.rw.rw == 2 && o.v.v == 1); @@ -138,11 +156,17 @@ main (int argc, char* argv[]) // Container. // { + typedef vector ulongs; + container o (1); o.ro.push_back (1); o.ro.push_back (2); + ulongs& co (const_cast (o.co)); + co.push_back (1); + co.push_back (2); + o.rw.push_back (1); o.rw.push_back (2); @@ -155,6 +179,9 @@ main (int argc, char* argv[]) o.ro[0]++; o.ro.pop_back (); + co[0]++; + co.pop_back (); + o.rw[0]++; o.rw.pop_back (); @@ -171,6 +198,7 @@ main (int argc, char* argv[]) } assert (o.ro.size () == 2 && o.ro[0] == 1 && o.ro[1] == 2 && + o.co.size () == 2 && o.co[0] == 1 && o.co[1] == 2 && o.rw.size () == 1 && o.rw[0] == 2); } @@ -221,6 +249,37 @@ main (int argc, char* argv[]) assert (rw_o.sv == 1 && rw_o.rw_sv == 2); } + + // Readonly object. + // + { + wrapper o (1, 1); + + { + transaction t (db->begin ()); + db->persist (o); + t.commit (); + } + + *o.pl = 2; + *o.cpl = 2; + o.pcl.reset (new unsigned long (2)); + const_cast (*o.cpcl) = 2; + + { + transaction t (db->begin ()); + db->update (o); + t.commit (); + } + + { + transaction t (db->begin ()); + db->load (1, o); + t.commit (); + } + + assert (*o.pl == 2 && *o.cpl == 2 && *o.pcl == 2 && *o.cpcl == 1); + } } catch (const odb::exception& e) { diff --git a/common/readonly/test.hxx b/common/readonly/test.hxx index a4cc55b..3a0095f 100644 --- a/common/readonly/test.hxx +++ b/common/readonly/test.hxx @@ -7,6 +7,7 @@ #define TEST_HXX #include +#include // std::auto_ptr #include @@ -16,11 +17,11 @@ struct simple { simple (unsigned long i, unsigned long x) - : id (i), ro (x), /*co (x),*/ rw (x) + : id (i), ro (x), co (x), rw (x) { } - simple ()/*: co (0)*/ {} + simple (): co (0) {} #pragma db id unsigned long id; @@ -28,7 +29,7 @@ struct simple #pragma db readonly unsigned long ro; - //const unsigned long co; + const unsigned long co; unsigned long rw; }; @@ -38,14 +39,17 @@ struct simple #pragma db object struct pointer { - pointer (unsigned long i, pointer* p = 0): id (i), ro (p), rw (p) {} - pointer (): ro (0), rw (0) {} + pointer (unsigned long i, pointer* p = 0): id (i), ro (p), co (p), rw (p) {} + pointer (): ro (0), co (0), rw (0) {} ~pointer () { delete ro; - if (ro != rw) + if (co != ro) + delete co; + + if (rw != ro && rw != co) delete rw; } @@ -55,6 +59,8 @@ struct pointer #pragma db readonly pointer* ro; + pointer* const co; + pointer* rw; }; @@ -73,12 +79,14 @@ struct ro_value #pragma db value struct value: ro_value { - value () {} - value (unsigned long x): ro_value (x), ro (x), rw (x) {} + value (): co (0) {} + value (unsigned long x): ro_value (x), ro (x), co (x), rw (x) {} #pragma db readonly unsigned long ro; + const unsigned long co; + unsigned long rw; }; @@ -86,7 +94,7 @@ struct value: ro_value struct composite { composite (unsigned long i, unsigned long x) - : id (i), ro (x), rw (x), v (x) + : id (i), ro (x), co (x), rw (x), v (x) { } @@ -98,6 +106,8 @@ struct composite #pragma db readonly value ro; + const value co; + value rw; ro_value v; }; @@ -116,6 +126,8 @@ struct container #pragma db readonly std::vector ro; + const std::vector co; + std::vector rw; }; @@ -160,4 +172,30 @@ struct rw_object: ro_object unsigned long rw_sv; }; +// Readonly wrappers. Here we make sure that only const wrappers with +// const wrapped types are automatically treated as readonly. +// +#pragma db object +struct wrapper +{ + wrapper (unsigned long i, unsigned long x) + : id (i), + pl (new unsigned long (x)), + cpl (new unsigned long (x)), + pcl (new unsigned long (x)), + cpcl (new unsigned long (x)) + { + } + + wrapper () {} + + #pragma db id + unsigned long id; + + std::auto_ptr pl; + const std::auto_ptr cpl; + std::auto_ptr pcl; + const std::auto_ptr cpcl; +}; + #endif // TEST_HXX -- cgit v1.1