customized smart-ptr based on std::shared_ptr
hopefully resolves long standing problems with odering and type relations of objects handled via smart ptr
This commit is contained in:
parent
89e71212e1
commit
2b529e3fac
5 changed files with 541 additions and 10 deletions
128
src/common/p.hpp
Normal file
128
src/common/p.hpp
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
P.hpp - customized shared_ptr with ordering and type relationships
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
/** @file p.hpp
|
||||
** customized refcounting smart pointer.
|
||||
** Template derived from std::tr1::shared_ptr adding total ordering and
|
||||
** type relationships implemented by forwarding to the pointees. In all other
|
||||
** respects, it should behave exactly as shared_ptr and is able to cooperate
|
||||
** and share ownership with other shared_ptr instantiations.
|
||||
**
|
||||
** By default different instantiations of shared_ptr are completely unrelated types,
|
||||
** even if using inherintance related type parameters for instantiation: a shared_ptr<Media>
|
||||
** isn't some kind-of shared_ptr<Asset> -- we need to do an explicit static_ptr_cast. Another
|
||||
** common problem is the definition of equality and ordering relations for shared_ptr:
|
||||
** equality is based on the equality of the managed pointers, while ordering is built upon
|
||||
** the ref count. While generally this may be a good compromise, in our case it hinders treating
|
||||
** the smart ptrs within the application almost as if they were the objects themselfs and proved
|
||||
** an obstacle for writing generic helper functions.
|
||||
**
|
||||
** the P template resolves these problems by implementing the ordering operators in terms of
|
||||
** the corresponding operators on the pointee and by allowing to specify a base class smart-ptr
|
||||
** as template parameter.
|
||||
**
|
||||
** @see asset.hpp
|
||||
** @see customsharedptrtest.cpp
|
||||
** @see orderingofassetstest.cpp
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LUMIERA_P_H
|
||||
#define LUMIERA_P_H
|
||||
|
||||
|
||||
#include <tr1/memory>
|
||||
|
||||
|
||||
namespace lumiera
|
||||
{
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::weak_ptr;
|
||||
|
||||
/**
|
||||
* customized refcounting smart pointer template, built upon
|
||||
* std::tr1::shared_ptr, but forwarding type relationships and
|
||||
* ordering operators to the pointee objects.
|
||||
* @param TAR the visible pointee type
|
||||
* @param the shared-ptr type used as implementation
|
||||
* @note if the BASE smart-ptr type used as implementation
|
||||
* implies another pointer type than the one used on
|
||||
* the interface (=type TAR), then every access to the
|
||||
* pointee causes an dynamic cast. Thus the pointee types
|
||||
* need to support RTTI.
|
||||
*/
|
||||
template<class TAR, class BASE =shared_ptr<TAR> >
|
||||
class P
|
||||
: public BASE
|
||||
{
|
||||
public:
|
||||
P ( ) : BASE() {}
|
||||
template<class Y> explicit P (Y* p) : BASE(p) {}
|
||||
template<class Y, class D> P (Y* p, D d) : BASE(p,d){}
|
||||
|
||||
P (P const& r) : BASE(r) {}
|
||||
template<class Y> P (shared_ptr<Y> const& r) : BASE(r) {}
|
||||
template<class Y> explicit P (weak_ptr<Y> const& wr) : BASE(wr) {}
|
||||
template<class Y> explicit P (std::auto_ptr<Y> & ar) : BASE(ar) {}
|
||||
|
||||
|
||||
P& operator= (P const& r) { BASE::operator= (r); return *this; }
|
||||
template<class Y> P& operator=(shared_ptr<Y> const& sr) { BASE::operator= (sr); return *this; }
|
||||
template<class Y> P& operator=(std::auto_ptr<Y> & ar) { BASE::operator= (ar); return *this; }
|
||||
|
||||
TAR* get() const { return dynamic_cast<TAR*> (BASE::get()); }
|
||||
TAR& operator*() const { return *get(); }
|
||||
TAR* operator->() const { return get(); }
|
||||
|
||||
void swap(P& b) { BASE::swap (b);}
|
||||
|
||||
|
||||
private: /* === friend operators injected into enclosing namespace for ADL === */
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator== (P const& p, P<_O_> const& q) { return (p && q)? (*p == *q) : (!p && !q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator!= (P const& p, P<_O_> const& q) { return (p && q)? (*p != *q) : !(!p && !q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator< (P const& p, P<_O_> const& q) { return (p && q) && (*p < *q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator> (P const& p, P<_O_> const& q) { return (p && q) && (*q < *p); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator<= (P const& p, P<_O_> const& q) { return (p && q)? (*p <= *q) : (!p && !q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator>= (P const& p, P<_O_> const& q) { return (p && q)? (*p >= *q) : (!p && !q); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace lumiera
|
||||
#endif
|
||||
|
|
@ -3,11 +3,11 @@
|
|||
## SConscript - SCons buildscript for tool subdirectory (called by SConstruct)
|
||||
##
|
||||
|
||||
Import('env','artifacts')
|
||||
Import('env','artifacts','core')
|
||||
|
||||
|
||||
# build the ubiquitous Hello World application (note: C source)
|
||||
artifacts['tools'] = [ env.Program('#$BINDIR/hello-world','hello.c')
|
||||
+ env.Program('#$BINDIR/try', 'try.cpp') #### to try out some feature:
|
||||
+ env.Program('#$BINDIR/try', ['try.cpp'] + core) #### to try out some feature:
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -7,18 +7,90 @@
|
|||
// execute with NOBUG_LOG='ttt:TRACE' bin/try
|
||||
// 1/08 - working out a static initialisation problem for Visitor (Tag creation)
|
||||
// 1/08 - check 64bit longs
|
||||
// 4/08 - comparison operators on shared_ptr<Asset>
|
||||
|
||||
|
||||
#include <nobug.h>
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
|
||||
#include <limits>
|
||||
#include "proc/asset/media.hpp"
|
||||
|
||||
|
||||
using std::string;
|
||||
using std::cout;
|
||||
|
||||
NOBUG_CPP_DEFINE_FLAG(test);
|
||||
|
||||
namespace lumiera
|
||||
{
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::weak_ptr;
|
||||
|
||||
template<class TAR, class BASE=std::tr1::shared_ptr<TAR> >
|
||||
class P
|
||||
: public BASE
|
||||
{
|
||||
public:
|
||||
P() : BASE() {}
|
||||
template<class Y> explicit P (Y* p) : BASE(p) {}
|
||||
template<class Y, class D> P (Y* p, D d) : BASE(p,d) {}
|
||||
|
||||
P (P const& r) : BASE(r) {}
|
||||
template<class Y> P (shared_ptr<Y> const& r) : BASE(r) {}
|
||||
template<class Y> explicit P (weak_ptr<Y> const& wr) : BASE(wr) {}
|
||||
template<class Y> explicit P (std::auto_ptr<Y> & ar) : BASE(ar) {}
|
||||
|
||||
private:
|
||||
// friend operators injected into enclosing namespace and found by ADL:
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator== (P const& p, P<_O_> const& q) { return (p && q)? (*p == *q) : (!p && !q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator!= (P const& p, P<_O_> const& q) { return (p && q)? (*p != *q) : !(!p && !q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator< (P const& p, P<_O_> const& q) { return (p && q) && (*p < *q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator> (P const& p, P<_O_> const& q) { return (p && q) && (*q < *p); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator<= (P const& p, P<_O_> const& q) { return (p && q)? (*p <= *q) : (!p && !q); }
|
||||
|
||||
template<typename _O_>
|
||||
friend inline bool
|
||||
operator>= (P const& p, P<_O_> const& q) { return (p && q)? (*p >= *q) : (!p && !q); }
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace asset
|
||||
{
|
||||
using lumiera::P;
|
||||
|
||||
|
||||
void
|
||||
doIt()
|
||||
{
|
||||
Asset::Ident key2("Try-1", Category(VIDEO));
|
||||
P<Asset> a1 = asset::Media::create(key2, "Name-1");
|
||||
|
||||
Asset::Ident key3("Try-2", Category(VIDEO));
|
||||
P<Media> a2 = asset::Media::create(key3, "Name-2");
|
||||
|
||||
cout << "a1 = " << str(a1);
|
||||
|
||||
bool yes = (a1 >= a2);
|
||||
enable_if<is_pAsset<PAsset>, string>::type yup;
|
||||
|
||||
cout << "\n yes=" << yes << " yup=" << typeid(*a1).name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
|
|
@ -26,12 +98,10 @@ int main (int argc, char* argv[])
|
|||
|
||||
NOBUG_INIT;
|
||||
|
||||
int64_t lol (1);
|
||||
cout << sizeof(lol)<< "\n";
|
||||
asset::doIt();
|
||||
|
||||
cout << "\ngulp\n";
|
||||
|
||||
cout << "long: "<< std::numeric_limits<long>::max()
|
||||
<<" 64: " << std::numeric_limits<int64_t>::max()
|
||||
<<"\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ TESTING "Component Test Suite: common and basic components" ./test-components --
|
|||
|
||||
|
||||
|
||||
|
||||
TEST "Hello test" HelloWorld_test 3 <<END
|
||||
out: This is how the world ends...
|
||||
out: This is how the world ends...
|
||||
|
|
@ -51,6 +50,11 @@ out: Standard Cmdlineformat:one two
|
|||
END
|
||||
|
||||
|
||||
TEST "CustomSharedPtr_test" CustomSharedPtr_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
TEST "ExceptionError_test" ExceptionError_test <<END
|
||||
out: caught: LUMIERA_ERROR_LIFE_AND_UNIVERSE:and everything? (don't panic)...the answer is: 42
|
||||
out: caught lumiera::Error: LUMIERA_ERROR_DERIVED:convoluted exception
|
||||
|
|
@ -103,6 +107,20 @@ out: dtor ~TargetObj(12) successfull
|
|||
END
|
||||
|
||||
|
||||
TEST "RemoveFromSet_test" RemoveFromSet_test <<END
|
||||
out: removed nothing ---> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ]
|
||||
out: removed 0 ---> [ 1, 2, 3, 4, 5, 6, 7, 8, 9, ]
|
||||
out: removed 9 ---> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, ]
|
||||
out: removed 5 ---> [ 0, 1, 2, 3, 4, 6, 7, 8, 9, ]
|
||||
out: removed 0 2 4 6 8 ---> [ 1, 3, 5, 7, 9, ]
|
||||
out: removed 1 3 5 7 9 ---> [ 0, 2, 4, 6, 8, ]
|
||||
out: removed 0 1 2 3 4 5 6 7 8 9 ---> [ ]
|
||||
out: removed 0 1 2 3 4 5 6 7 8 ---> [ 9, ]
|
||||
out: removed 1 2 3 4 5 6 7 8 9 ---> [ 0, ]
|
||||
out: removed 0 1 2 3 4 6 7 8 9 ---> [ 5, ]
|
||||
END
|
||||
|
||||
|
||||
TEST "SanitizedIdentifier_test" SanitizedIdentifier_test <<END
|
||||
out: 'Word' --> 'Word'
|
||||
out: 'a Sentence' --> 'a_Sentence'
|
||||
|
|
|
|||
315
tests/components/common/customsharedptrtest.cpp
Normal file
315
tests/components/common/customsharedptrtest.cpp
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
CustomSharedPtr(Test) - refcounting, equality and comparisons
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
|
||||
#include "common/test/run.hpp"
|
||||
#include "common/util.hpp"
|
||||
|
||||
#include "common/p.hpp"
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
using std::string;
|
||||
|
||||
|
||||
namespace asset
|
||||
{
|
||||
namespace test
|
||||
{
|
||||
using lumiera::P;
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::weak_ptr;
|
||||
|
||||
|
||||
struct X
|
||||
: boost::totally_ordered<X>
|
||||
{
|
||||
long x_;
|
||||
|
||||
X(long x=0) : x_(x) {}
|
||||
operator long () { return x_; }
|
||||
|
||||
bool operator< (const X& ox) const { return x_ < ox.x_; }
|
||||
bool operator== (const X& ox) const { return x_ == ox.x_; }
|
||||
|
||||
virtual ~X() {} // using RTTI
|
||||
};
|
||||
|
||||
struct XX : public X
|
||||
{
|
||||
long xx_;
|
||||
|
||||
XX(long x=0) : X(x), xx_(x+1) {}
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* @test assure correct behaviour of lumiera's custom shared-ptr,
|
||||
* including ADL of operators, shared ownership, typing
|
||||
* and ordering
|
||||
* @see lumiera::P
|
||||
*/
|
||||
class CustomSharedPtr_test : public Test
|
||||
{
|
||||
virtual void
|
||||
run (Arg arg)
|
||||
{
|
||||
check_refcounting ();
|
||||
check_shared_ownership ();
|
||||
check_type_relations ();
|
||||
check_ordering ();
|
||||
}
|
||||
|
||||
|
||||
/** @test smart-ptr basic behaviour */
|
||||
void
|
||||
check_refcounting ()
|
||||
{
|
||||
P<X> p1 (new X(7));
|
||||
ASSERT (p1);
|
||||
ASSERT (1 == p1.use_count());
|
||||
ASSERT (7 == p1->x_);
|
||||
|
||||
{
|
||||
P<X> p2 (new X(9));
|
||||
ASSERT (1 == p2.use_count());
|
||||
|
||||
p2.swap (p1);
|
||||
ASSERT (1 == p1.use_count());
|
||||
ASSERT (1 == p2.use_count());
|
||||
|
||||
p2 = p1;
|
||||
ASSERT (2 == p1.use_count());
|
||||
ASSERT (2 == p2.use_count());
|
||||
}
|
||||
|
||||
ASSERT (1 == p1.use_count());
|
||||
ASSERT (9 == p1->x_);
|
||||
|
||||
p1.reset();
|
||||
ASSERT (0 == p1.use_count());
|
||||
ASSERT (!p1);
|
||||
}
|
||||
|
||||
|
||||
/** @test cooperation with other shared-ptr types */
|
||||
void
|
||||
check_shared_ownership ()
|
||||
{
|
||||
std::auto_ptr<X> au (new X(22));
|
||||
ASSERT (au.get());
|
||||
|
||||
P<X> pX (au);
|
||||
ASSERT (!au.get());
|
||||
ASSERT (pX);
|
||||
ASSERT (1 == pX.use_count());
|
||||
ASSERT (22 == pX->x_);
|
||||
|
||||
weak_ptr<X> wX (pX);
|
||||
ASSERT (wX.lock());
|
||||
ASSERT (1 == pX.use_count());
|
||||
|
||||
shared_ptr<X> sp1 (wX);
|
||||
shared_ptr<X> sp2 (pX);
|
||||
shared_ptr<X> sp3; sp3 = pX;
|
||||
|
||||
ASSERT (22 == sp3->x_);
|
||||
ASSERT (4 == pX.use_count());
|
||||
ASSERT (*pX == *sp1);
|
||||
ASSERT (*sp1 == *sp2);
|
||||
ASSERT (*sp2 == *sp3);
|
||||
|
||||
P<X> pX2;
|
||||
pX2.swap(pX);
|
||||
ASSERT (!pX);
|
||||
ASSERT (0 == pX.use_count());
|
||||
ASSERT (4 == pX2.use_count());
|
||||
|
||||
P<X, P<X> > pXX (pX2); // a different type, but compatible pointers
|
||||
pX2 = pX;
|
||||
ASSERT (!pX2);
|
||||
ASSERT (0 == pX2.use_count());
|
||||
ASSERT (4 == pXX.use_count());
|
||||
|
||||
sp3 = sp2 = sp1 = pX;
|
||||
ASSERT (22 == pXX->x_);
|
||||
ASSERT (1 == pXX.use_count());
|
||||
ASSERT (!sp1);
|
||||
ASSERT (!sp2);
|
||||
ASSERT (!sp3);
|
||||
|
||||
ASSERT (22 == wX.lock()->x_);
|
||||
ASSERT (1 == pXX.use_count());
|
||||
|
||||
pXX.reset();
|
||||
ASSERT (!pXX);
|
||||
ASSERT (!wX.lock());
|
||||
}
|
||||
|
||||
|
||||
/** @test building type relationships on smart-ptrs */
|
||||
void
|
||||
check_type_relations ()
|
||||
{
|
||||
P<X> pX; // Base: shared_ptr<X>
|
||||
P<XX> pX1; // Base: shared_ptr<XX>
|
||||
P<XX,P<X> > pX2; // Base: P<X>
|
||||
P<XX,shared_ptr<X> > pX3; // Base: shared_ptr<X>
|
||||
P<XX,shared_ptr<long> > pLo;// Base: shared_ptr<long>
|
||||
P<X,string> pLoL; // Base: std::string
|
||||
P<string> pLoLoL; // Base: shared_ptr<string>
|
||||
|
||||
ASSERT (INSTANCEOF (P<X>, &pX));
|
||||
ASSERT (INSTANCEOF (shared_ptr<X>, &pX));
|
||||
|
||||
ASSERT ( INSTANCEOF (shared_ptr<XX>, &pX1));
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<X>, &pX1)); // doesn't compile (no RTTI) -- that's OK
|
||||
// ASSERT (!INSTANCEOF (P<X>, &pX1));
|
||||
|
||||
ASSERT ( INSTANCEOF (shared_ptr<X>, &pX2));
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<XX>, &pX2));
|
||||
ASSERT ( INSTANCEOF (P<X>, &pX2));
|
||||
|
||||
ASSERT ( INSTANCEOF (shared_ptr<X>, &pX3));
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<XX>, &pX3));
|
||||
// ASSERT (!INSTANCEOF (P<X>, &pX3));
|
||||
|
||||
ASSERT ( INSTANCEOF (shared_ptr<long>, &pLo));
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<X>, &pLo));
|
||||
// ASSERT (!INSTANCEOF (P<X>, &pLo));
|
||||
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<long>, &pLoL));
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<X>, &pLoL));
|
||||
// ASSERT (!INSTANCEOF (P<X>, &pLoL));
|
||||
ASSERT ( INSTANCEOF (string, &pLoL));
|
||||
|
||||
ASSERT ( INSTANCEOF (shared_ptr<string>, &pLoLoL));
|
||||
// ASSERT (!INSTANCEOF (string, &pLoLoL));
|
||||
// ASSERT (!INSTANCEOF (shared_ptr<X>, &pLoLoL));
|
||||
|
||||
pX = pX1; // OK: pointee subtype...
|
||||
pX = pX2; // invokes shared_ptr<X>::operator= (shared_ptr<X> const&)
|
||||
pX = pX3;
|
||||
// pX = pLo; // similar, but long* not asignable to X*
|
||||
// pX = pLoL; // similar, but string* not asignable to X*
|
||||
// pX = pLoLoL; // same...
|
||||
// you can't do much with the "LoLo"-Types,
|
||||
// their types and pointee types's relations don't match
|
||||
|
||||
pX.reset (new XX(5));
|
||||
ASSERT (5 == *pX); // implicit conversion from X to long
|
||||
|
||||
pX2 = pX; // works, because both are implemented in terms of shared_ptr<X>
|
||||
ASSERT (5 == pX2->x_);
|
||||
ASSERT (6 == pX2->xx_); // using the XX interface (performing dynamic downcast)
|
||||
|
||||
pX3.reset (new X(7)); // again works because implemented in terms of shared_ptr<X>
|
||||
pX2 = pX3; // same
|
||||
ASSERT (pX2); // both contain indeed a valid pointer....
|
||||
ASSERT (pX3);
|
||||
ASSERT (! pX2.get()); // but dynamic cast to XX at access fails
|
||||
ASSERT (! pX3.get());
|
||||
}
|
||||
|
||||
|
||||
/** @test equality and ordering operators forwarded to pointee */
|
||||
void
|
||||
check_ordering ()
|
||||
{
|
||||
typedef P<X> PX;
|
||||
typedef P<XX,PX> PXX;
|
||||
|
||||
PX pX1 (new X(3));
|
||||
PX pX2 (new XX(5));
|
||||
PX pX3, pX4, pX5, pX6;
|
||||
PXX pXX (new XX(7));
|
||||
|
||||
pX3 = pXX;
|
||||
pX4.reset(new X(*pXX));
|
||||
|
||||
ASSERT ( (pX1 == pX1)); // reflexivity
|
||||
ASSERT (!(pX1 != pX1));
|
||||
ASSERT (!(pX1 < pX1));
|
||||
ASSERT (!(pX1 > pX1));
|
||||
ASSERT ( (pX1 <= pX1));
|
||||
ASSERT ( (pX1 >= pX1));
|
||||
|
||||
ASSERT (!(pX1 == pX2)); // compare to same ptr type with larger pointee of subtype
|
||||
ASSERT ( (pX1 != pX2));
|
||||
ASSERT ( (pX1 < pX2));
|
||||
ASSERT (!(pX1 > pX2));
|
||||
ASSERT ( (pX1 <= pX2));
|
||||
ASSERT (!(pX1 >= pX2));
|
||||
|
||||
ASSERT (!(pX2 == pXX)); // compare to ptr subtype with larger pointee of same subtype
|
||||
ASSERT ( (pX2 != pXX));
|
||||
ASSERT ( (pX2 < pXX));
|
||||
ASSERT (!(pX2 > pXX));
|
||||
ASSERT ( (pX2 <= pXX));
|
||||
ASSERT (!(pX2 >= pXX));
|
||||
|
||||
ASSERT (!(pX1 == pXX)); // transitively compare to ptr subtype with larger pointee of subtype
|
||||
ASSERT ( (pX1 != pXX));
|
||||
ASSERT ( (pX1 < pXX));
|
||||
ASSERT (!(pX1 > pXX));
|
||||
ASSERT ( (pX1 <= pXX));
|
||||
ASSERT (!(pX1 >= pXX));
|
||||
|
||||
ASSERT ( (pX3 == pXX)); // compare ptr to subtype ptr both referring to same pointee
|
||||
ASSERT (!(pX3 != pXX));
|
||||
ASSERT (!(pX3 < pXX));
|
||||
ASSERT (!(pX3 > pXX));
|
||||
ASSERT ( (pX3 <= pXX));
|
||||
ASSERT ( (pX3 >= pXX));
|
||||
|
||||
ASSERT ( (pX4 == pXX)); // compare ptr to subtype ptr both referring to different but equal pointees
|
||||
ASSERT (!(pX4 != pXX));
|
||||
ASSERT (!(pX4 < pXX));
|
||||
ASSERT (!(pX4 > pXX));
|
||||
ASSERT ( (pX4 <= pXX));
|
||||
ASSERT ( (pX4 >= pXX));
|
||||
|
||||
ASSERT (!(pXX == pX5)); // compare subtype ptr to empty ptr: "unequal but not orderable"
|
||||
ASSERT ( (pXX != pX5));
|
||||
ASSERT (!(pXX < pX5));
|
||||
ASSERT (!(pXX > pX5));
|
||||
ASSERT (!(pXX <= pX5));
|
||||
ASSERT (!(pXX >= pX5));
|
||||
|
||||
ASSERT ( (pX5 == pX6)); // compare two empty ptrs: "equal, aequivalent but not orderable"
|
||||
ASSERT (!(pX5 != pX6));
|
||||
ASSERT (!(pX5 < pX6));
|
||||
ASSERT (!(pX5 > pX6));
|
||||
ASSERT ( (pX5 <= pX6));
|
||||
ASSERT ( (pX5 >= pX6));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (CustomSharedPtr_test, "unit common");
|
||||
|
||||
|
||||
|
||||
} // namespace test
|
||||
|
||||
} // namespace asset
|
||||
Loading…
Reference in a new issue