www.pudn.com > Loki.rar > Test_SmartPtr.cpp


#include  
#include  
#include  
#include  
#include "SmartPtr.h" 
 
#if defined(TEST_LOKI_ORIG) 
namespace Loki 
{ 
    template 
    < 
        typename T, 
        template  class OwnershipPolicy = RefCounted, 
        class ConversionPolicy = DisallowConversion, 
        template  class CheckingPolicy = AssertCheck, 
        template  class StoragePolicy = DefaultSPStorage 
    > 
    struct SmartPtrDef 
    { 
        typedef SmartPtr 
        < 
            T, 
            OwnershipPolicy, 
            ConversionPolicy, 
            CheckingPolicy, 
            StoragePolicy 
        > 
        type; 
    }; 
} // namespace Loki 
#endif // defined(TEST_LOKI_ORIG) 
 
using namespace ::Loki; 
 
struct A  
{  
    A()          { ++s_instCount; } 
    A(const A &) { ++s_instCount; } 
    virtual ~A() { --s_instCount; }  
     
    virtual const char *name() const = 0; 
 
    static void AssertInstCount() 
    { 
        assert(s_instCount == 0); 
    } 
 
private: 
    static int s_instCount; 
}; 
 
int A::s_instCount = 0; 
 
struct B : A  
{ 
    virtual const char *name() const 
    { 
        return "B"; 
    } 
}; 
 
struct C : A  
{ 
    virtual const char *name() const 
    { 
        return "C"; 
    } 
}; 
 
template 
struct PrintA 
{ 
    void operator()(const SmartPtr_A &spA) const 
    { 
        std::cout << spA->name() << ", "; 
    } 
}; 
 
void Test_SmartPtr() 
{ 
    typedef SmartPtrDef::type SmartPtr_A; 
    typedef SmartPtrDef::type SmartPtr_B; 
    typedef SmartPtrDef::type SmartPtr_C; 
 
    SmartPtr_B     spB(new B); 
    SmartPtr_C     spC(new C); 
 
    SmartPtr_A     spA1(spB); 
    SmartPtr_A     spA2(spC); 
 
    std::cout << spA1->name() << std::endl; 
    std::cout << spA2->name() << std::endl; 
 
    spA1 = spA2; 
    spA2 = spB; 
 
    std::cout << spA1->name() << std::endl; 
     
    if (spA2 == spA1) 
    { 
        std::cout << spA2->name() << std::endl; 
    } 
 
    Reset(spA2, new C); 
     
    if (spA2) 
    { 
        std::cout << spA2->name() << std::endl; 
    } 
 
    std::vector vectorA; 
 
    for (unsigned i = 0 ; i < 10 ; ++i) 
    { 
        if ((i % 3) == 0) 
        { 
            vectorA.push_back(new B); 
        } 
        else 
        { 
            vectorA.push_back(new C); 
        } 
    } 
     
    for (unsigned i = 0 ; i < 10 ; ++i) 
    { 
        vectorA.push_back(vectorA[i]); 
    } 
 
    std::for_each(vectorA.begin(), vectorA.end(), PrintA()); 
 
    std::cout << std::endl; 
} 
 
// I know it's ugly code duplication but the template version kills VC7 
void Test_SmartPtrRL() 
{ 
    typedef SmartPtrDef::type SmartPtr_A; 
    typedef SmartPtrDef::type SmartPtr_B; 
    typedef SmartPtrDef::type SmartPtr_C; 
 
    SmartPtr_B     spB(new B); 
    SmartPtr_C     spC(new C); 
 
    SmartPtr_A     spA1(spB); 
    SmartPtr_A     spA2(spC); 
 
    std::cout << spA1->name() << std::endl; 
    std::cout << spA2->name() << std::endl; 
 
    spA1 = spA2; 
    spA2 = spB; 
 
    std::cout << spA1->name() << std::endl; 
     
    if (spA2 == spA1) 
    { 
        std::cout << spA2->name() << std::endl; 
    } 
 
    Reset(spA2, new C); 
     
    if (spA2) 
    { 
        std::cout << spA2->name() << std::endl; 
    } 
 
    std::vector vectorA; 
 
    for (unsigned i = 0 ; i < 10 ; ++i) 
    { 
        if ((i % 3) == 0) 
        { 
            vectorA.push_back(new B); 
        } 
        else 
        { 
            vectorA.push_back(new C); 
        } 
    } 
 
    for (unsigned i = 0 ; i < 10 ; ++i) 
    { 
        vectorA.push_back(vectorA[i]); 
    } 
 
    std::for_each(vectorA.begin(), vectorA.end(), PrintA()); 
 
    std::cout << std::endl; 
} 
 
void Test_SmartPtrMT() 
{ 
#define MyRefCountedMT RefCountedMTAdj::RefCountedMT 
 
    typedef SmartPtrDef::type SmartPtr_A; 
    typedef SmartPtrDef::type SmartPtr_B; 
    typedef SmartPtrDef::type SmartPtr_C; 
 
#undef MyRefCountedMT 
 
    SmartPtr_B     spB(new B); 
    SmartPtr_C     spC(new C); 
 
    SmartPtr_A     spA1(spB); 
    SmartPtr_A     spA2(spC); 
 
    std::cout << spA1->name() << std::endl; 
    std::cout << spA2->name() << std::endl; 
 
    spA1 = spA2; 
    spA2 = spB; 
 
    std::cout << spA1->name() << std::endl; 
     
    if (spA2 == spA1) 
    { 
        std::cout << spA2->name() << std::endl; 
    } 
 
    Reset(spA2, new C); 
     
    if (spA2) 
    { 
        std::cout << spA2->name() << std::endl; 
    } 
 
    std::vector vectorA; 
 
    for (unsigned i = 0 ; i < 10 ; ++i) 
    { 
        if ((i % 3) == 0) 
        { 
            vectorA.push_back(new B); 
        } 
        else 
        { 
            vectorA.push_back(new C); 
        } 
    } 
 
    for (unsigned i = 0 ; i < 10 ; ++i) 
    { 
        vectorA.push_back(vectorA[i]); 
    } 
 
    std::for_each(vectorA.begin(), vectorA.end(), PrintA()); 
 
    std::cout << std::endl; 
} 
 
void Test_RejectNull() 
{ 
    typedef SmartPtrDef::type SmartPtr_A; 
 
    try { 
        SmartPtr_A     spA; 
    } catch (std::exception &ex) { 
        std::cout << "Reject Default: " << ex.what() << std::endl; 
    } 
 
    try { 
        SmartPtr_A     spA(0); 
    } catch (std::exception &ex) { 
        std::cout << "Reject Null: " << ex.what() << std::endl; 
    } 
} 
 
int main() 
{ 
    Test_SmartPtr(); 
    Test_SmartPtrRL(); 
    Test_SmartPtrMT(); 
    Test_RejectNull(); 
 
    A::AssertInstCount(); 
}