ItemWrapper unit test pass. Closes #476
This commit is contained in:
parent
e5ab9d73eb
commit
97faf3dcb8
3 changed files with 86 additions and 39 deletions
|
|
@ -87,16 +87,7 @@ namespace wrapper {
|
|||
};
|
||||
|
||||
|
||||
|
||||
namespace impl {
|
||||
template<typename TY>
|
||||
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<TY &>
|
||||
: public BoolCheckable<ItemWrapper<TY &> >
|
||||
{
|
||||
// mutable
|
||||
|
||||
TY * content_;
|
||||
|
||||
|
||||
|
|
@ -278,5 +270,23 @@ namespace wrapper {
|
|||
|
||||
|
||||
|
||||
/** allow equality comparison if the wrapped types are comparable */
|
||||
template<typename TY>
|
||||
inline bool
|
||||
operator== (ItemWrapper<TY> const& w1, ItemWrapper<TY> const& w2)
|
||||
{
|
||||
return (!w1 && !w2)
|
||||
|| ( w1 && w2 && (*w1)==(*w2));
|
||||
}
|
||||
|
||||
template<typename TY>
|
||||
inline bool
|
||||
operator!= (ItemWrapper<TY> const& w1, ItemWrapper<TY> const& w2)
|
||||
{
|
||||
return !(w1 == w2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::wrap
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -321,7 +321,8 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
PLANNED "inline val/ref wrapper" ItemWrapper_test <<END
|
||||
TEST "inline val/ref wrapper" ItemWrapper_test <<END
|
||||
out: ItemWrapper: sizeof\( .+ItemWrapper.+ ) =
|
||||
END
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#include "lib/wrapper.hpp"
|
||||
|
||||
//#include <boost/lexical_cast.hpp>
|
||||
//#include <iostream>
|
||||
#include <iostream>
|
||||
//#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
|
@ -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<ulong> (l1, l2);
|
||||
verifyWrapper<ulong&> (l1, l2);
|
||||
#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 475 !!!!!!!!!
|
||||
verifyWrapper<ulong*> (&l1, &l2);
|
||||
verifyWrapper<ulong*> ((0), &l2);
|
||||
verifyWrapper<ulong*> (&l1, (0));
|
||||
|
|
@ -99,13 +108,10 @@ namespace test{
|
|||
verifyWrapper<string&> (s1, s2);
|
||||
verifyWrapper<string*> (&s1, &s2);
|
||||
|
||||
verifyWrapper<Tracker> (t1, t2);
|
||||
verifyWrapper<Tracker&> (t1, t2);
|
||||
verifyWrapper<Tracker*> (&t1, &t2);
|
||||
|
||||
verifyWrapper<const char*> (cp, "Lumiera");
|
||||
#endif //////////////////////////////////////////////////////////////////////////////////////TODO using yet undefined facilities.....!!!!!
|
||||
|
||||
|
||||
verifySaneInstanceHandling();
|
||||
verifyWrappedRef ();
|
||||
}
|
||||
|
||||
|
|
@ -117,6 +123,8 @@ namespace test{
|
|||
const ItemWrapper<X> wrap(val);
|
||||
ASSERT (wrap);
|
||||
|
||||
cout << "ItemWrapper: " << showSizeof(wrap) << endl;
|
||||
|
||||
ItemWrapper<X> copy1 (wrap);
|
||||
ItemWrapper<X> copy2;
|
||||
ItemWrapper<X> 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<Tracker> (t1, t2);
|
||||
verifyWrapper<Tracker&> (t1, t2);
|
||||
verifyWrapper<Tracker*> (&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<int&> refWrap;
|
||||
ASSERT (!refWrap);
|
||||
|
|
@ -182,10 +218,10 @@ namespace test{
|
|||
ASSERT (x == 10);
|
||||
|
||||
ItemWrapper<int*> 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.....!!!!!
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue