From 97faf3dcb844746b7a984092f410eeead0c9f8b5 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Mon, 21 Dec 2009 07:52:58 +0100 Subject: [PATCH] ItemWrapper unit test pass. Closes #476 --- src/lib/wrapper.hpp | 38 +++++++++------ tests/40components.tests | 3 +- tests/lib/item-wrapper-test.cpp | 84 +++++++++++++++++++++++---------- 3 files changed, 86 insertions(+), 39 deletions(-) diff --git a/src/lib/wrapper.hpp b/src/lib/wrapper.hpp index b37f79ce7..7772965ab 100644 --- a/src/lib/wrapper.hpp +++ b/src/lib/wrapper.hpp @@ -87,16 +87,7 @@ namespace wrapper { }; - - namespace impl { - template - struct ItemWrapperStorage - { - char content_[sizeof(TY)]; - char created_; - - }; - } + /** * Universal value/ref wrapper behaving like a pointer. @@ -108,7 +99,7 @@ namespace wrapper { * * The purpose of this template is to be able to remember * pretty much any kind of value or pointer or reference, - * and to subsume this handling in a single template. + * and to subsume this handling within a single template. * An example would be to remember the value yielded * by a function, without any further assumptions * regarding this function. @@ -173,7 +164,7 @@ namespace wrapper { if (!ref.isValid()) discard(); else - (*this) = (*ref); + this->operator= (*ref); return *this; } @@ -182,7 +173,7 @@ namespace wrapper { ItemWrapper& operator= (X const& something) ///< accept anything assignable to TY { - if (isSameObject (something, access() )) + if (!isSameObject (something, access() )) { if (created_) access() = something; @@ -217,6 +208,7 @@ namespace wrapper { } }; + /** * Specialisation of the ItemWrapper to deal with references, * as if they were pointer values. Allows the reference value @@ -226,7 +218,7 @@ namespace wrapper { class ItemWrapper : public BoolCheckable > { -// mutable + TY * content_; @@ -278,5 +270,23 @@ namespace wrapper { + /** allow equality comparison if the wrapped types are comparable */ + template + inline bool + operator== (ItemWrapper const& w1, ItemWrapper const& w2) + { + return (!w1 && !w2) + || ( w1 && w2 && (*w1)==(*w2)); + } + + template + inline bool + operator!= (ItemWrapper const& w1, ItemWrapper const& w2) + { + return !(w1 == w2); + } + + + }} // namespace lib::wrap #endif diff --git a/tests/40components.tests b/tests/40components.tests index 2101294bf..6aae03697 100644 --- a/tests/40components.tests +++ b/tests/40components.tests @@ -321,7 +321,8 @@ return: 0 END -PLANNED "inline val/ref wrapper" ItemWrapper_test < -//#include +#include //#include #include #include @@ -48,14 +48,27 @@ namespace test{ // using std::vector; using std::string; using lib::test::randStr; -// using std::cout; -// using std::endl; + using lib::test::showSizeof; + using std::cout; + using std::endl; - namespace { // Test data + namespace { // Test helper: yet another ctor/dtor counting class + + long cntTracker = 0; - ///////////TODO + struct Tracker + { + uint i_; + + Tracker() : i_(rand() % 500) { ++cntTracker; } + Tracker(Tracker const& ot) : i_(ot.i_) { ++cntTracker; } + ~Tracker() { --cntTracker; } + }; + + bool operator== (Tracker const& t1, Tracker const& t2) { return t1.i_ == t2.i_; } + bool operator!= (Tracker const& t1, Tracker const& t2) { return t1.i_ != t2.i_; } } // (END) Test data @@ -68,14 +81,13 @@ namespace test{ /******************************************************************************* * @test use the ItemWrapper to define inline-storage holding values, * pointers and references. Verify correct behaviour in each case, - * including assignment, empty check, invalid dereferentiation. + * including (self)assignment, empty check, invalid dereferentiation. * */ class ItemWrapper_test : public Test { - virtual void run (Arg) { @@ -84,12 +96,9 @@ namespace test{ string s1 (randStr(50)); string s2 (randStr(50)); const char* cp (s1.c_str()); -// Tracker t1; -// Tracker t2; verifyWrapper (l1, l2); verifyWrapper (l1, l2); -#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 475 !!!!!!!!! verifyWrapper (&l1, &l2); verifyWrapper ((0), &l2); verifyWrapper (&l1, (0)); @@ -99,13 +108,10 @@ namespace test{ verifyWrapper (s1, s2); verifyWrapper (&s1, &s2); - verifyWrapper (t1, t2); - verifyWrapper (t1, t2); - verifyWrapper (&t1, &t2); - verifyWrapper (cp, "Lumiera"); -#endif //////////////////////////////////////////////////////////////////////////////////////TODO using yet undefined facilities.....!!!!! + + verifySaneInstanceHandling(); verifyWrappedRef (); } @@ -117,6 +123,8 @@ namespace test{ const ItemWrapper wrap(val); ASSERT (wrap); + cout << "ItemWrapper: " << showSizeof(wrap) << endl; + ItemWrapper copy1 (wrap); ItemWrapper copy2; ItemWrapper empty; @@ -125,17 +133,13 @@ namespace test{ ASSERT (!copy2); ASSERT (false == bool(empty)); -#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 475 !!!!!!!!! ASSERT (wrap == copy1); -#endif //////////////////////////////////////////////////////////////////////////////////////TODO using yet undefined facilities.....!!!!! ASSERT (wrap != copy2); ASSERT (wrap != empty); copy2 = copy1; ASSERT (copy2); -#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 475 !!!!!!!!! ASSERT (wrap == copy2); -#endif //////////////////////////////////////////////////////////////////////////////////////TODO using yet undefined facilities.....!!!!! ASSERT (wrap != empty); copy2 = otherVal; @@ -154,21 +158,53 @@ namespace test{ ASSERT (otherVal == *copy2); ASSERT (wrap != copy1); ASSERT (wrap != copy2); + + copy1 = empty; // assign empty to discard value + copy1 = copy1; // self-assign empty + ASSERT (!copy1); + copy1 = copy2; + ASSERT (otherVal == *copy1); + copy1 = copy1; // self-assign (will be suppressed) + ASSERT (otherVal == *copy1); + copy1 = *copy1; // self-assign also detected in this case + ASSERT (otherVal == *copy2); + + ASSERT (copy1); copy1.reset(); ASSERT (!copy1); -#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 475 !!!!!!!!! ASSERT (empty == copy1); -#endif //////////////////////////////////////////////////////////////////////////////////////TODO using yet undefined facilities.....!!!!! ASSERT (copy2 != copy1); VERIFY_ERROR (BOTTOM_VALUE, *copy1 ); }; + /** @test verify that ctor and dtor calls are balanced, + * even when assigning and self-assigning. + */ + void + verifySaneInstanceHandling() + { + cntTracker = 0; + { + Tracker t1; + Tracker t2; + + verifyWrapper (t1, t2); + verifyWrapper (t1, t2); + verifyWrapper (&t1, &t2); + + } + ASSERT (0 == cntTracker); + } + + + /** @test verify especially that we can wrap and handle + * a reference "value" in a pointer-like manner + */ void verifyWrappedRef () { -#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 475 !!!!!!!!! int x = 5; ItemWrapper refWrap; ASSERT (!refWrap); @@ -182,10 +218,10 @@ namespace test{ ASSERT (x == 10); ItemWrapper ptrWrap (& *refWrap); - ASSERT (isSameObject (*ptrWrap, x)); + ASSERT ( isSameObject (**ptrWrap, x)); + ASSERT (!isSameObject ( *ptrWrap, &x)); **ptrWrap += 13; ASSERT (x == 23); -#endif //////////////////////////////////////////////////////////////////////////////////////TODO using yet undefined facilities.....!!!!! }