no message
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@35 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
8c599321c7
commit
69936e7e81
27 changed files with 2073 additions and 495 deletions
31
tools/RegressionTest/AllTest/AllTest.cpp
Normal file
31
tools/RegressionTest/AllTest/AllTest.cpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
extern void Test_TypeList();
|
||||
extern void Test_SmallObj();
|
||||
extern void Test_Functor();
|
||||
extern void Test_Singleton();
|
||||
extern void Test_SmartPtr();
|
||||
extern void Test_ObjectFactory();
|
||||
extern void Test_AbstractFactory();
|
||||
extern void Test_Vistor();
|
||||
extern void Test_MultiMethods();
|
||||
extern void Test_Threads();
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
Test_TypeList();
|
||||
Test_SmartPtr();
|
||||
Test_Singleton();
|
||||
Test_Threads();
|
||||
/*Test_SmallObj();
|
||||
Test_Functor();
|
||||
*/
|
||||
|
||||
/*Test_ObjectFactory();
|
||||
Test_AbstractFactory();
|
||||
Test_Vistor();
|
||||
Test_MultiMethods();
|
||||
*/
|
||||
system("pause");
|
||||
};
|
|
@ -2,8 +2,8 @@
|
|||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.00"
|
||||
Name="LokiRegressionTest"
|
||||
ProjectGUID="{E7FC3709-2BA7-4EAB-AF6B-B3ABC9BE493B}"
|
||||
Name="AllTest"
|
||||
ProjectGUID="{59800972-3512-4147-9E8F-F5239C241F77}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
|
@ -23,20 +23,18 @@
|
|||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="4"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/LokiTest.exe"
|
||||
OutputFile="$(OutDir)/AllTest.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/LokiTest.pdb"
|
||||
ProgramDatabaseFile="$(OutDir)/AllTest.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
|
@ -69,8 +67,6 @@
|
|||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
ForceConformanceInForLoopScope="TRUE"
|
||||
RuntimeTypeInfo="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
|
@ -79,7 +75,7 @@
|
|||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/LokiTest.exe"
|
||||
OutputFile="$(OutDir)/AllTest.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
|
@ -104,60 +100,34 @@
|
|||
</Configurations>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Name="Test"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
<File
|
||||
RelativePath="..\..\SDK\Engine\Loki\Loki.hpp">
|
||||
RelativePath="AllTest.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LokiTest.cpp">
|
||||
RelativePath="..\Test_Singleton.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LokiTest.h">
|
||||
RelativePath="..\Test_SmartPtr.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LokiTestTypes.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
<File
|
||||
RelativePath="LokiTest_TypeList.h">
|
||||
RelativePath="..\Test_Threads.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LokiTest_TypeManip.h">
|
||||
RelativePath="..\Test_TypeList.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="LokiTest_TypeTraits.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Loki"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\..\SDK\Loki\NullType.h">
|
||||
RelativePath="..\..\..\Singleton.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\SDK\Loki\VC7\TypeInfo.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\SDK\Loki\VC7\TypeList.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\SDK\Loki\VC7\TypeManip.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\SDK\Loki\VC7\TypeTraits.h">
|
||||
RelativePath="..\..\..\SmallObj.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="ReadMe.txt">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
|
@ -1,81 +0,0 @@
|
|||
// LokiTest.cpp : Defines the entry point for the console application.
|
||||
//
|
||||
|
||||
#include <conio.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
//#define LOKI_USE_REFERENCE
|
||||
|
||||
#include <Loki\static_check.h>
|
||||
#include <Loki\NullType.h>
|
||||
#include <Loki\TypeInfo.h>
|
||||
#include <Loki\TypeManip.h>
|
||||
#include <Loki\TypeList.h>
|
||||
#include <Loki\TypeTraits.h>
|
||||
|
||||
//The test use macros so that you can comment out any test
|
||||
// that result in compilation errors and continue testing
|
||||
// the remaining components
|
||||
//TODO break into seperate files, use boost methods to test
|
||||
// successful & unsuccessful compilations
|
||||
|
||||
#include "LokiTestTypes.h"
|
||||
#include "LokiTest_TypeManip.h"
|
||||
#include "LokiTest_TypeList.h"
|
||||
#include "LokiTest_TypeInfo.h"
|
||||
#include "LokiTest_TypeTraits.h"
|
||||
|
||||
//LOKI_TEST_TYPE2TYPE_HEADER
|
||||
LOKI_TEST_TYPE2TYPE_HEADER_BROKEN_PATTERN_MATCHING
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
argc;
|
||||
argv;
|
||||
//Compile-Time Assertions
|
||||
STATIC_CHECK(true, ThisShouldCompile);
|
||||
//STATIC_CHECK(false, ThisShouldNotCompile);
|
||||
|
||||
LOKI_TEST_NULLTYPE;
|
||||
|
||||
//Test TypeManip
|
||||
LOKI_TEST_INT2TYPE;
|
||||
//LOKI_TEST_TYPE2TYPE;
|
||||
LOKI_TEST_TYPE2TYPE_BROKEN_PATTERN_MATCHING;
|
||||
LOKI_TEST_SELECT;
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) //constant conditionals
|
||||
LOKI_TEST_CONVERSION;
|
||||
#pragma warning(pop)
|
||||
|
||||
//TypeInfo
|
||||
LOKI_TEST_TYPEINFO;
|
||||
|
||||
//TypeTraits
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) //constant conditionals
|
||||
{
|
||||
//TODO figure out correct results
|
||||
cout<<"Testing TypeTraits"<<endl;
|
||||
DUMP_TRAITS(int);
|
||||
DUMP_TRAITS(float);
|
||||
DUMP_TRAITS(volatile unsigned int);
|
||||
DUMP_TRAITS(const float);
|
||||
cout<<"Are the const & volatile qualifers handled correctly?"<<endl;
|
||||
cout<<endl<<endl;
|
||||
}
|
||||
#pragma warning(pop)
|
||||
|
||||
//Test TypeList
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4127) //constant conditionals
|
||||
LOKI_TEST_LENGTH;
|
||||
#pragma warning(pop)
|
||||
|
||||
getch();
|
||||
return 0;
|
||||
}
|
||||
//*/
|
|
@ -1,37 +0,0 @@
|
|||
#pragma once
|
||||
#ifndef __LOKITESTTYPES_H
|
||||
#define __LOKITESTTYPES_H
|
||||
//Types to use in the test
|
||||
namespace Loki
|
||||
{
|
||||
namespace RegressionTest
|
||||
{
|
||||
struct Complex
|
||||
{
|
||||
float r,i;
|
||||
};
|
||||
struct Complex_Convertable
|
||||
{
|
||||
Complex_Convertable(){}
|
||||
Complex_Convertable(float x) : r(x), i(0) {}
|
||||
float r,i;
|
||||
};
|
||||
struct TwoWay
|
||||
{
|
||||
TwoWay(double x) : r(x) {}
|
||||
operator double(){return r;}
|
||||
double r;
|
||||
};
|
||||
struct SuperClass
|
||||
{
|
||||
};
|
||||
struct SubClass : SuperClass
|
||||
{
|
||||
};
|
||||
typedef TYPELIST_1(Loki::NullType) tyNullList;
|
||||
typedef TYPELIST_1(void) tyList1;
|
||||
typedef TYPELIST_2(int, double) tyList2;
|
||||
typedef TYPELIST_5(std::vector<int>, Loki::RegressionTest::Complex, void, int, double) tyList5;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
|
||||
namespace Loki
|
||||
{
|
||||
namespace Test
|
||||
{
|
||||
struct CTBaseType
|
||||
{
|
||||
};
|
||||
struct CTDerivedType : CTBaseType
|
||||
{
|
||||
};
|
||||
struct RTBaseType
|
||||
{
|
||||
virtual ~RTBaseType(){}
|
||||
virtual const char*const name(){return "BaseType";}
|
||||
};
|
||||
struct RTDerivedType : RTBaseType
|
||||
{
|
||||
virtual const char*const name(){return "DerivedType";}
|
||||
};
|
||||
}//ns Test
|
||||
}//ns Loki
|
||||
|
||||
//TODO Test the other operators and before
|
||||
#define LOKI_TEST_TYPEINFO\
|
||||
{\
|
||||
cout<<"Testing TypeInfo"<<endl;\
|
||||
Loki::TypeInfo type_CTDerived(typeid(Loki::Test::CTDerivedType));\
|
||||
\
|
||||
Loki::Test::CTDerivedType* pDerived=0; pDerived;\
|
||||
if(typeid(*pDerived) == type_CTDerived)\
|
||||
cout<<"Compile-time TypeInfo works"<<endl;\
|
||||
else\
|
||||
cout<<"Compile-time TypeInfo is ***BROKEN***"<<endl;\
|
||||
\
|
||||
try\
|
||||
{\
|
||||
Loki::TypeInfo type_RTDerived(typeid(Loki::Test::RTDerivedType));\
|
||||
Loki::Test::RTBaseType* pBase = new Loki::Test::RTDerivedType;\
|
||||
pBase;\
|
||||
if(typeid(*pBase) == type_RTDerived)\
|
||||
cout<<"Run-time TypeInfo works"<<endl;\
|
||||
else\
|
||||
{\
|
||||
cout<<"Run-time TypeInfo is ***BROKEN***"<<endl;\
|
||||
cout<<"Is RTTI enabled?"<<endl;\
|
||||
cout<<"Compiler thinks pBase points to a ";\
|
||||
cout<<typeid(*pBase).name()<<endl;\
|
||||
}\
|
||||
delete pBase;\
|
||||
}\
|
||||
catch(...)\
|
||||
{\
|
||||
cout<<"Run-time TypeInfo is ***BROKEN***"<<endl;\
|
||||
cout<<"Run-time TypeInfo check threw - Is RTTI enabled?"<<endl;\
|
||||
}\
|
||||
cout<<endl<<endl;\
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
|
||||
#define LOKI_TEST_LENGTH\
|
||||
{\
|
||||
cout<<"Testing Length"<<endl;\
|
||||
cout<<"Length of List1: "<<Loki::TL::Length<Loki::RegressionTest::tyList1>::value<<endl;\
|
||||
cout<<"Length of List2: "<<Loki::TL::Length<Loki::RegressionTest::tyList2>::value<<endl;\
|
||||
cout<<"Length of List5: "<<Loki::TL::Length<Loki::RegressionTest::tyList5>::value<<endl;\
|
||||
if ( (Loki::TL::Length<Loki::RegressionTest::tyList1>::value==1) &&\
|
||||
(Loki::TL::Length<Loki::RegressionTest::tyList2>::value==2) &&\
|
||||
(Loki::TL::Length<Loki::RegressionTest::tyList5>::value==5) )\
|
||||
cout<<"Normal cases work"<<endl;\
|
||||
else\
|
||||
cout<<"Normal cases are ***BROKEN***"<<endl;\
|
||||
cout<<"Length of NullType: "<<Loki::TL::Length<Loki::NullType>::value<<endl;\
|
||||
cout<<"Length of NullList: "<<Loki::TL::Length<Loki::RegressionTest::tyNullList>::value<<endl;\
|
||||
if ( (Loki::TL::Length<Loki::NullType>::value==0) &&\
|
||||
(Loki::TL::Length<Loki::RegressionTest::tyNullList>::value==0) )\
|
||||
cout<<"Pathological cases work"<<endl;\
|
||||
else\
|
||||
cout<<"Pathological cases are ***BROKEN***"<<endl;\
|
||||
cout<<endl<<endl;\
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void TypeAt()
|
||||
{
|
||||
cout<<endl<<"Testing TypeAt"<<endl;
|
||||
//typedef TypeAt<List2, -1>::Result FailsToCompile;
|
||||
typedef TypeAt<List2, 0>::Result FirstType;
|
||||
typedef TypeAt<List2, 1>::Result SecondType;
|
||||
typedef TypeAt<List2, 2>::Result ThirdType;
|
||||
typedef TypeAt<List2, 3>::Result FourthType;
|
||||
typedef TypeAt<List2, 4>::Result FifthType;
|
||||
cout<<typeid(FirstType).name()<<endl;
|
||||
cout<<typeid(SecondType).name()<<endl;
|
||||
cout<<typeid(ThirdType).name()<<endl;
|
||||
cout<<typeid(FourthType).name()<<endl;
|
||||
cout<<typeid(FifthType).name()<<endl;
|
||||
}
|
||||
/*
|
||||
void IndexOf()
|
||||
{
|
||||
cout<<endl<<"Testing IndexOf"<<endl;
|
||||
cout<<"IndexOf int: "<<IndexOf<List2, int>::value<<endl;
|
||||
cout<<"IndexOf double: "<<IndexOf<List2, double>::value<<endl;
|
||||
cout<<"IndexOf vector: "<<IndexOf<List2, vector<int> >::value<<endl;
|
||||
cout<<"IndexOf Complex: "<<IndexOf<List2, Complex>::value<<endl;
|
||||
cout<<"IndexOf long: "<<IndexOf<List2, long>::value<<endl;
|
||||
}
|
||||
/*
|
||||
void Append()
|
||||
{
|
||||
cout <<endl<<"Testing Append" << endl;
|
||||
typedef Append<NullType, NullType>::Result List0;
|
||||
typedef Append<List0, bool>::Result List1;
|
||||
typedef Append<List1, double>::Result List2;
|
||||
typedef Append<List2, NullType>:: Result List3;
|
||||
cout << Length<List0>::value << endl;
|
||||
cout << Length<List1>::value << "\t";
|
||||
cout << typeid(TypeAt<List1, Length<List1>::value -1 >::Result).name() << endl;
|
||||
cout << Length<List2>::value << "\t";
|
||||
cout << typeid(TypeAt<List2, Length<List2>::value -1>::Result).name() << endl;
|
||||
cout << Length<List3>::value << "\t";
|
||||
cout << typeid(TypeAt<List3, Length<List3>::value -1>::Result).name() << endl;
|
||||
}
|
||||
/*
|
||||
void Erase()
|
||||
{
|
||||
cout <<endl<< "Testing Erase" << endl;
|
||||
cout <<"Erase is broken, notice the size goes up"<<endl;
|
||||
cout << Length<List1>::value << "\t"
|
||||
<< typeid(TypeAt<List1, Length<List1>::value -1 >::Result).name() << endl;
|
||||
cout << Length<List2>::value << "\t"
|
||||
<< typeid(TypeAt<List2, Length<List2>::value -1>::Result).name() << endl;
|
||||
cout << Length<List3>::value << "\t"
|
||||
<< typeid(TypeAt<List3, Length<List3>::value -1>::Result).name() << endl;
|
||||
}
|
||||
*/
|
|
@ -1,164 +0,0 @@
|
|||
|
||||
#include "LokiTestTypes.h"
|
||||
using std::endl;
|
||||
using std::cout;
|
||||
|
||||
//You're not using a C++ compiler if this fails.
|
||||
//Requires #include <Loki\NullType.h>
|
||||
#define LOKI_TEST_NULLTYPE\
|
||||
{\
|
||||
Loki::NullType nullTest;\
|
||||
cout<<"Testing NullType"<<endl;\
|
||||
cout<<"Sizeof nullType: "<<sizeof(nullTest)<<endl;\
|
||||
cout<<endl<<endl;\
|
||||
}
|
||||
|
||||
#define LOKI_TEST_SELECT\
|
||||
{\
|
||||
cout<<"Testing Select"<<endl;\
|
||||
typedef Loki::Select<true, void, Loki::NullType>::Result TrueType;\
|
||||
typedef Loki::Select<false, int, double>::Result FalseType;\
|
||||
cout<<"True case: "<<typeid(TrueType).name()<<endl;\
|
||||
cout<<"False case: "<<typeid(FalseType).name()<<endl;\
|
||||
cout<<endl<<endl;\
|
||||
}
|
||||
|
||||
|
||||
//TODO Need more test cases for _STRICT varaints
|
||||
//TODO What is the proper conversion results to/from void?
|
||||
#define LOKI_TEST_CONVERSION\
|
||||
{\
|
||||
cout<<"Testing Conversion"<<endl;\
|
||||
typedef Loki::Conversion<int, int> tySame;\
|
||||
typedef Loki::Conversion<int, Loki::RegressionTest::Complex> tyNoCon;\
|
||||
typedef Loki::Conversion<int, Loki::RegressionTest::Complex_Convertable> tyCon;\
|
||||
typedef Loki::Conversion<int, Loki::RegressionTest::TwoWay> ty2Way;\
|
||||
typedef Loki::Conversion<void, int> tyVoid;\
|
||||
cout<< tySame::sameType<<" <int, int>::sameType" <<endl;\
|
||||
cout<< tySame::exists<<" <int, int>::exists" <<endl;\
|
||||
cout<< tySame::exists2Way<<" <int, int>::exists2Way" <<endl;\
|
||||
if (tySame::sameType && tySame::exists && tySame::exists2Way)\
|
||||
cout<<"Works for same type"<<endl;\
|
||||
else\
|
||||
cout<<"Same type is ***BROKEN***"<<endl;\
|
||||
cout<<endl;\
|
||||
\
|
||||
cout<< tyNoCon::sameType<<" <int, Complex>::sameType" <<endl;\
|
||||
cout<< tyNoCon::exists<<" <int, Complex>::exists" <<endl;\
|
||||
cout<< tyNoCon::exists2Way<<" <int, Complex>::exists2Way" <<endl;\
|
||||
if (!tyNoCon::sameType && !tyNoCon::exists && !tyNoCon::exists2Way)\
|
||||
cout<<"Works for non-convertibles"<<endl;\
|
||||
else\
|
||||
cout<<"Non-convertibles is ***BROKEN***"<<endl;\
|
||||
cout<<endl;\
|
||||
\
|
||||
cout<< tyCon::sameType<<" <int, Complex_Convertable>::sameType" <<endl;\
|
||||
cout<< tyCon::exists<<" <int, Complex_Convertable>::exists" <<endl;\
|
||||
cout<< tyCon::exists2Way<<" <int, Complex_Convertable>::exists2Way" <<endl;\
|
||||
if (!tyCon::sameType && tyCon::exists && !tyCon::exists2Way)\
|
||||
cout<<"Works for one-way convertible"<<endl;\
|
||||
else\
|
||||
cout<<"One-way convertible is ***BROKEN***"<<endl;\
|
||||
cout<<endl;\
|
||||
\
|
||||
cout<< ty2Way::sameType<<" <int, TwoWay>::sameType" <<endl;\
|
||||
cout<< ty2Way::exists<<" <int, TwoWay>::exists" <<endl;\
|
||||
cout<< ty2Way::exists2Way<<" <int, TwoWay>::exists2Way" <<endl;\
|
||||
if (!ty2Way::sameType && ty2Way::exists && ty2Way::exists2Way)\
|
||||
cout<<"Works for two-way convertibles"<<endl;\
|
||||
else\
|
||||
cout<<"Two-way convertibles is ***BROKEN***"<<endl;\
|
||||
cout<<endl;\
|
||||
\
|
||||
cout<< tyVoid::sameType<<" <void, int>::sameType" <<endl;\
|
||||
cout<< tyVoid::exists<<" <void, int>::exists" <<endl;\
|
||||
cout<< tyVoid::exists2Way<<" <void, int>::exists2Way" <<endl;\
|
||||
if (!tyVoid::sameType && !tyVoid::exists && !tyVoid::exists2Way)\
|
||||
cout<<"Works for void"<<endl;\
|
||||
else\
|
||||
cout<<"Void conversion is ***BROKEN***"<<endl;\
|
||||
cout<<"What is the correct behavior here?"<<endl;\
|
||||
cout<<endl;\
|
||||
\
|
||||
cout<< SUPERSUBCLASS(Loki::RegressionTest::SuperClass, Loki::RegressionTest::SubClass)<<" SuperSubClass Super&Sub"<<endl;\
|
||||
cout<< SUPERSUBCLASS_STRICT(Loki::RegressionTest::SuperClass, Loki::RegressionTest::SubClass)<<" SuperSubClass_Strict Super&Sub"<<endl;\
|
||||
cout<< SUPERSUBCLASS(void, Loki::RegressionTest::SubClass)<<" to void*"<<endl;\
|
||||
cout<< SUPERSUBCLASS_STRICT(void, Loki::RegressionTest::SubClass)<<" _Strict to void*"<<endl;\
|
||||
cout<< SUPERSUBCLASS(Loki::RegressionTest::SubClass, Loki::RegressionTest::SuperClass)<<" SubSuperClass Sub&Super"<<endl;\
|
||||
cout<<endl<<endl;\
|
||||
}
|
||||
|
||||
#define LOKI_TEST_INT2TYPE\
|
||||
{\
|
||||
cout<<"Testing Int2Type"<<endl;\
|
||||
typedef Loki::Int2Type<0> tyZero;\
|
||||
typedef Loki::Int2Type<1> tyOne;\
|
||||
typedef Loki::Int2Type<-1> tyNegOne;\
|
||||
cout<<" Zero: "<<typeid(tyZero).name()<<endl;\
|
||||
cout<<" One: "<<typeid(tyOne).name()<<endl;\
|
||||
cout<<"Neg One: "<<typeid(tyNegOne).name()<<endl;\
|
||||
cout<<endl<<endl;\
|
||||
}
|
||||
|
||||
//I think this example is an undesirable way to solve this
|
||||
// problem, but we're just exercising Type2Type
|
||||
//MSVC7 has a template pattern matching problem that prevents this
|
||||
// example solution from compiling correctly.
|
||||
// Type2Type does work, but the solution it was created for doesn't
|
||||
#define LOKI_TEST_TYPE2TYPE_HEADER\
|
||||
struct Widget\
|
||||
{\
|
||||
Widget(int x, int reserved)\
|
||||
{\
|
||||
assert(reserved==-1);\
|
||||
}\
|
||||
};\
|
||||
struct NewWidget\
|
||||
{\
|
||||
NewWidget(int x)\
|
||||
{}\
|
||||
};\
|
||||
template<class T, class U>\
|
||||
T* Create(const U& arg, Loki::Type2Type<T>)\
|
||||
{\
|
||||
return new T(arg);\
|
||||
}\
|
||||
template<class U>\
|
||||
Widget* Create(const U& arg, Loki::Type2Type<Widget>)\
|
||||
{\
|
||||
return new Widget(arg, -1);\
|
||||
}
|
||||
#define LOKI_TEST_TYPE2TYPE\
|
||||
{\
|
||||
cout<<"Testing Type2Type"<<endl;\
|
||||
NewWidget* pNewWidget = Create(4, Loki::Type2Type<NewWidget>() );\
|
||||
delete pNewWidget;\
|
||||
Widget* pWidget = Create(100, Loki::Type2Type<Widget>() );\
|
||||
delete pWidget;\
|
||||
cout<<"Used Type2Type"<<endl;\
|
||||
}
|
||||
|
||||
#define LOKI_TEST_TYPE2TYPE_HEADER_BROKEN_PATTERN_MATCHING\
|
||||
struct Widget\
|
||||
{\
|
||||
Widget(int x, int reserved)\
|
||||
{\
|
||||
cc=x;\
|
||||
assert(reserved==-1);\
|
||||
}\
|
||||
int cc;\
|
||||
};\
|
||||
template<class U>\
|
||||
Widget* Create(const U& arg, Loki::Type2Type<Widget>)\
|
||||
{\
|
||||
return new Widget(arg, -1);\
|
||||
}
|
||||
#define LOKI_TEST_TYPE2TYPE_BROKEN_PATTERN_MATCHING\
|
||||
{\
|
||||
cout<<"Testing Type2Type"<<endl;\
|
||||
Widget* pWidget = Create(100, Loki::Type2Type<Widget>() );\
|
||||
delete pWidget;\
|
||||
cout<<"Used Type2Type"<<endl;\
|
||||
cout<<endl<<endl;\
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
#define DUMP_TRAIT(type, trait)\
|
||||
if(Loki::TypeTraits<type>::trait)\
|
||||
cout<<#trait<<", ";
|
||||
|
||||
#define DUMP_TRAITS(type)\
|
||||
{\
|
||||
cout<<"("<<#type<<") ";\
|
||||
DUMP_TRAIT(type, isPointer);\
|
||||
DUMP_TRAIT(type, isReference);\
|
||||
DUMP_TRAIT(type, isMemberPointer);\
|
||||
DUMP_TRAIT(type, isStdUnsignedInt);\
|
||||
DUMP_TRAIT(type, isStdSignedInt);\
|
||||
DUMP_TRAIT(type, isStdIntegral);\
|
||||
DUMP_TRAIT(type, isStdFloat);\
|
||||
DUMP_TRAIT(type, isStdArith);\
|
||||
DUMP_TRAIT(type, isStdFundamental);\
|
||||
DUMP_TRAIT(type, isUnsignedInt);\
|
||||
DUMP_TRAIT(type, isSignedInt);\
|
||||
DUMP_TRAIT(type, isIntegral);\
|
||||
DUMP_TRAIT(type, isFloat);\
|
||||
DUMP_TRAIT(type, isArith);\
|
||||
DUMP_TRAIT(type, isFundamental);\
|
||||
DUMP_TRAIT(type, isConst);\
|
||||
DUMP_TRAIT(type, isVolatile);\
|
||||
cout<<endl;\
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 7.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LokiRegressionTest", "LokiRegressionTest.vcproj", "{E7FC3709-2BA7-4EAB-AF6B-B3ABC9BE493B}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AllTest", "AllTest\AllTest.vcproj", "{59800972-3512-4147-9E8F-F5239C241F77}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
|
@ -9,10 +9,10 @@ Global
|
|||
GlobalSection(ProjectDependencies) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{E7FC3709-2BA7-4EAB-AF6B-B3ABC9BE493B}.Debug.ActiveCfg = Debug|Win32
|
||||
{E7FC3709-2BA7-4EAB-AF6B-B3ABC9BE493B}.Debug.Build.0 = Debug|Win32
|
||||
{E7FC3709-2BA7-4EAB-AF6B-B3ABC9BE493B}.Release.ActiveCfg = Release|Win32
|
||||
{E7FC3709-2BA7-4EAB-AF6B-B3ABC9BE493B}.Release.Build.0 = Release|Win32
|
||||
{59800972-3512-4147-9E8F-F5239C241F77}.Debug.ActiveCfg = Debug|Win32
|
||||
{59800972-3512-4147-9E8F-F5239C241F77}.Debug.Build.0 = Debug|Win32
|
||||
{59800972-3512-4147-9E8F-F5239C241F77}.Release.ActiveCfg = Release|Win32
|
||||
{59800972-3512-4147-9E8F-F5239C241F77}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
235
tools/RegressionTest/Simulate_PS.cpp
Normal file
235
tools/RegressionTest/Simulate_PS.cpp
Normal file
|
@ -0,0 +1,235 @@
|
|||
//
|
||||
// in this source code I will demonstrate via example the "canonical" and compliant way of
|
||||
// simulating class template partial specialization and function templates partial ordering
|
||||
// both are not implemented in VC7 and from the simulation you will see that they are closely related
|
||||
// in the example I will simulate the Append class template which have 4 specializations
|
||||
// Part of the sample was also tested with Comeau C/C++ 4.3.0 online
|
||||
// although the code is perfectly compliant many compilers (like bcc 5.6 and gcc 3.03 which support partial stuff) can't
|
||||
// handle it (maybe some workaround can help).
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include <Loki\Typelist.h>
|
||||
#include <Loki\static_check.h>
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
//
|
||||
// Simulating function templates partial ordering (14.5.5.2):
|
||||
// The following simple example demonstrate the whole idea
|
||||
// template<typename T> void f(T);
|
||||
// template<typename T> void f(T*);
|
||||
// the functions are partial ordered and T* is more specialized then T
|
||||
// compiler which is not supporting partial ordering will decide that f((int*)0)
|
||||
// is ambiguous. We must resolve the ambiguity our self.
|
||||
// There is more then one way of doing it but I like the following:
|
||||
// struct A{};
|
||||
// struct B : A{};
|
||||
// template<typename T> void f(T, A);
|
||||
// template<typename T> void f(T*, B);
|
||||
// template<typename T> void f(T x) { f(x, B()); }
|
||||
// for pointers f(T*, B) is better then f(T, A) when the call is f(ptr, B());
|
||||
//
|
||||
|
||||
//
|
||||
// This template will help us to "order" the function templates.
|
||||
//
|
||||
template<unsigned I>
|
||||
struct Order : Order<I - 1> {};
|
||||
|
||||
template<>
|
||||
struct Order<0> {};
|
||||
|
||||
template<unsigned I>
|
||||
struct TypeTag
|
||||
{
|
||||
typedef char (&X)[I];
|
||||
};
|
||||
|
||||
//
|
||||
// This template class simulate the detection of the best specialization
|
||||
//
|
||||
template<class TList, class T>
|
||||
class AppendPattern
|
||||
{
|
||||
// you can call me insane but VC7 fails without the following typedefs
|
||||
typedef TypeTag<2>::X X2;
|
||||
typedef TypeTag<3>::X X3;
|
||||
typedef TypeTag<4>::X X4;
|
||||
|
||||
// Match Append<NullType, NullType>
|
||||
static TypeTag<1>::X Match(Type2Type<NullType>, Type2Type<NullType>, Order<1>);
|
||||
|
||||
// Match Append<NullType, T>
|
||||
template<typename T1>
|
||||
static TypeTag<2>::X Match(Type2Type<NullType>, Type2Type<T1>, Order<0>);
|
||||
|
||||
// Match Append<NullType, Typelist<Head, Tail>>
|
||||
template <class Head, class Tail>
|
||||
static TypeTag<3>::X Match(Type2Type<NullType>, Type2Type<Typelist<Head, Tail> >, Order<1>);
|
||||
|
||||
// Match Append<Typelist<Head, Tail>, T>
|
||||
template <class Head, class Tail, typename T1>
|
||||
static TypeTag<4>::X Match(Type2Type<Typelist<Head, Tail> >, Type2Type<T1>, Order<0>);
|
||||
|
||||
static Type2Type<TList> Get1();
|
||||
static Type2Type<T> Get2();
|
||||
|
||||
// VC will fail if the sizeof is written directly to the TypeTag
|
||||
enum { value = sizeof(Match( Get1(), Get2(), Order<1>() )) };
|
||||
|
||||
public:
|
||||
typedef TypeTag<value> Result;
|
||||
};
|
||||
|
||||
template <class TList, class T> class Append2;
|
||||
|
||||
//
|
||||
// This template class simulate the detection of the partial specialization
|
||||
// The append helper simulate the partial specialized class templates with
|
||||
// explicit specialization that represent the selected specialization and
|
||||
// nested class template which implement the specialization
|
||||
//
|
||||
template<typename Tag> struct AppendHelper;
|
||||
|
||||
template<>
|
||||
struct AppendHelper< TypeTag<1> >
|
||||
{ // Append<NullType, NullType>
|
||||
template <class, class>
|
||||
struct In
|
||||
{
|
||||
typedef NullType Result;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AppendHelper< TypeTag<2> >
|
||||
{ // Append<NullType, T>
|
||||
template <class, class T>
|
||||
struct In
|
||||
{
|
||||
typedef TYPELIST_1(T) Result;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AppendHelper< TypeTag<3> >
|
||||
{ // Append<NullType, Typelist<Head, Tail> >
|
||||
template <class, class TList>
|
||||
struct In
|
||||
{
|
||||
typedef typename TList::Head Head;
|
||||
typedef typename TList::Tail Tail;
|
||||
|
||||
typedef Typelist<Head, Tail> Result;
|
||||
//typedef TList Result;
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AppendHelper< TypeTag<4> >
|
||||
{ // Append<Typelist<Head, Tail>, T>
|
||||
template <class TList, class T>
|
||||
struct In
|
||||
{
|
||||
typedef typename TList::Head Head;
|
||||
typedef typename TList::Tail Tail;
|
||||
|
||||
typedef Typelist<Head, typename Append2<Tail, T>::Result> Result;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <class TList, class T>
|
||||
class Append2
|
||||
{
|
||||
// First we detect the best specialization
|
||||
typedef typename AppendPattern<TList, T>::Result Pattern;
|
||||
|
||||
public:
|
||||
|
||||
// Insatiate the best specialization
|
||||
typedef typename AppendHelper<Pattern>::
|
||||
template In<TList, T>::Result
|
||||
Result;
|
||||
};
|
||||
|
||||
//
|
||||
// Lets toy with the simulated Append
|
||||
//
|
||||
|
||||
typedef struct IncompType *IncompPtr;
|
||||
|
||||
struct A1 {};
|
||||
struct B1 : A1 {};
|
||||
|
||||
struct A2 {};
|
||||
struct B2 : A2 {};
|
||||
|
||||
struct C1 : B1 {};
|
||||
struct C2 : B2 {};
|
||||
struct D1 : C1, C2 {};
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
template<typename TList>
|
||||
struct PrintTypelist
|
||||
{
|
||||
PrintTypelist()
|
||||
{
|
||||
typedef typename TList::Head Head;
|
||||
typedef typename TList::Tail Tail;
|
||||
|
||||
printf("%s ,", typeid(Head).name());
|
||||
|
||||
PrintTypelist<Tail>();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PrintTypelist<NullType>
|
||||
{
|
||||
PrintTypelist()
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
};
|
||||
|
||||
template<class TList, typename T>
|
||||
void Test_Append2()
|
||||
{
|
||||
typedef typename TL::Append<TList, T>::Result typelist1_t;
|
||||
typedef typename Append2<TList, T>::Result typelist2_t;
|
||||
|
||||
// Assert (compile time) that typelist1_t and typelist2_t are the same type
|
||||
STATIC_CHECK((Conversion<typelist1_t, typelist2_t>::sameType), Append2_Failed);
|
||||
|
||||
PrintTypelist<typelist1_t>();
|
||||
PrintTypelist<typelist2_t>();
|
||||
}
|
||||
|
||||
void Test_Append()
|
||||
{
|
||||
typedef TL::MakeTypeList<int, A1, A2>::Result typelist1_t;
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**>::Result typelist2_t;
|
||||
|
||||
Test_Append2<NullType, NullType>();
|
||||
Test_Append2<NullType, typelist2_t>();
|
||||
Test_Append2<typelist1_t, NullType>();
|
||||
Test_Append2<NullType, int>();
|
||||
Test_Append2<typelist1_t, int[10]>();
|
||||
Test_Append2<typelist1_t, typelist2_t>();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
Test_Append();
|
||||
system("pause");
|
||||
}
|
||||
|
148
tools/RegressionTest/Test_AbstractFactory.cpp
Normal file
148
tools/RegressionTest/Test_AbstractFactory.cpp
Normal file
|
@ -0,0 +1,148 @@
|
|||
#include <iostream>
|
||||
#include <memory>
|
||||
#include "AbstractFactory.h"
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
|
||||
struct Enemy
|
||||
{
|
||||
virtual Enemy* Clone() = 0;
|
||||
virtual ~Enemy() {};
|
||||
};
|
||||
|
||||
struct Soldier : Enemy
|
||||
{
|
||||
virtual Soldier* Clone() = 0;
|
||||
virtual const char *SoldierName() const = 0;
|
||||
};
|
||||
|
||||
struct Monster : Enemy
|
||||
{
|
||||
virtual Monster* Clone() = 0;
|
||||
virtual const char *MonsterName() const = 0;
|
||||
};
|
||||
|
||||
struct SuperMonster : Enemy
|
||||
{
|
||||
virtual SuperMonster* Clone() = 0;
|
||||
virtual const char *SuperMonsterName() const = 0;
|
||||
};
|
||||
|
||||
typedef AbstractFactory
|
||||
<
|
||||
TYPELIST_3(Soldier, Monster, SuperMonster)
|
||||
>
|
||||
AbstractEnemyFactory;
|
||||
|
||||
class SillySoldier
|
||||
: public Soldier
|
||||
{
|
||||
public:
|
||||
explicit SillySoldier(const char *name = "Anonymous Silly Soldier")
|
||||
: name_(name)
|
||||
{}
|
||||
|
||||
virtual SillySoldier* Clone()
|
||||
{
|
||||
return new SillySoldier("Cloned Silly Soldier");
|
||||
}
|
||||
|
||||
virtual const char *SoldierName() const { return name_; }
|
||||
|
||||
private:
|
||||
const char *name_;
|
||||
};
|
||||
|
||||
class SillyMonster
|
||||
: public Monster
|
||||
{
|
||||
public:
|
||||
explicit SillyMonster(const char *name = "Anonymous Silly Monster")
|
||||
: name_(name)
|
||||
{}
|
||||
|
||||
virtual SillyMonster* Clone()
|
||||
{
|
||||
return new SillyMonster("Cloned Silly Moster");
|
||||
}
|
||||
|
||||
virtual const char *MonsterName() const { return name_; }
|
||||
|
||||
private:
|
||||
const char *name_;
|
||||
};
|
||||
|
||||
class SillySuperMonster
|
||||
: public SuperMonster
|
||||
{
|
||||
public:
|
||||
explicit SillySuperMonster(const char *name = "Anonymous Silly SuperMonster")
|
||||
: name_(name)
|
||||
{}
|
||||
|
||||
virtual SillySuperMonster* Clone()
|
||||
{
|
||||
return new SillySuperMonster("Cloned Silly SuperMoster");
|
||||
}
|
||||
|
||||
virtual const char *SuperMonsterName() const { return name_; }
|
||||
|
||||
private:
|
||||
const char *name_;
|
||||
};
|
||||
|
||||
typedef ConcreteFactory
|
||||
<
|
||||
AbstractEnemyFactory,
|
||||
OpNewFactoryUnit,
|
||||
TYPELIST_3(SillySoldier, SillyMonster, SillySuperMonster)
|
||||
>
|
||||
EasyLevelEnemyFactory;
|
||||
|
||||
typedef ConcreteFactory
|
||||
<
|
||||
AbstractEnemyFactory,
|
||||
PrototypeFactoryUnit
|
||||
>
|
||||
EnemyFactory;
|
||||
|
||||
void print_names(AbstractEnemyFactory &abstEnemyFactory)
|
||||
{
|
||||
using std::auto_ptr;
|
||||
|
||||
auto_ptr<Soldier> apSoldier(abstEnemyFactory.Create<Soldier>());
|
||||
|
||||
std::cout << apSoldier->SoldierName() << std::endl;
|
||||
|
||||
|
||||
auto_ptr<Monster> apMonster(abstEnemyFactory.Create<Monster>());
|
||||
|
||||
std::cout << apMonster->MonsterName() << std::endl;
|
||||
|
||||
|
||||
auto_ptr<SuperMonster> apSuperMonster(abstEnemyFactory.Create<SuperMonster>());
|
||||
|
||||
std::cout << apSuperMonster->SuperMonsterName() << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
EasyLevelEnemyFactory testEasyLevelEnemyFactory;
|
||||
|
||||
print_names(testEasyLevelEnemyFactory);
|
||||
|
||||
EnemyFactory testEnemyFactory;
|
||||
|
||||
SillySoldier testSillySoldier;
|
||||
testEnemyFactory.SetPrototype(&testSillySoldier);
|
||||
|
||||
SillyMonster testSillyMonster;
|
||||
testEnemyFactory.SetPrototype(&testSillyMonster);
|
||||
|
||||
SillySuperMonster testSillySuperMonster;
|
||||
testEnemyFactory.SetPrototype(&testSillySuperMonster);
|
||||
|
||||
print_names(testEnemyFactory);
|
||||
}
|
||||
|
35
tools/RegressionTest/Test_Factory.cpp
Normal file
35
tools/RegressionTest/Test_Factory.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include "Factory.h"
|
||||
#include "AbstractFactory.h"
|
||||
|
||||
template<typename T>
|
||||
void print_type()
|
||||
{
|
||||
printf("%s\n", typeid(T).name());
|
||||
}
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
struct A1 {}; struct A2 {}; struct A3 {}; struct A4 {};
|
||||
struct A5 {}; struct A6 {}; struct A7 {}; struct A8 {};
|
||||
|
||||
typedef TL::MakeTypeList<A1, A2, A3, A4, A5, A6, A7, A8>::Result typelist1_t;
|
||||
|
||||
struct Abst : AbstractFactory<typelist1_t> {};
|
||||
|
||||
int main()
|
||||
{
|
||||
Factory<A1, int> a;
|
||||
CloneFactory<A1> b;
|
||||
|
||||
typedef AbstractFactory<typelist1_t> abst_t;
|
||||
|
||||
struct AA1 : ConcreteFactory<abst_t, OpNewFactoryUnit> {};
|
||||
AA1 a1;
|
||||
|
||||
struct AA2 : ConcreteFactory<Abst, OpNewFactoryUnit> {};
|
||||
|
||||
AA2 a2;
|
||||
}
|
||||
|
44
tools/RegressionTest/Test_Functor.cpp
Normal file
44
tools/RegressionTest/Test_Functor.cpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <cstdio>
|
||||
#include "Functor.h"
|
||||
|
||||
using namespace Loki;
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
explicit A(int number)
|
||||
: number_(number)
|
||||
{}
|
||||
|
||||
int Get() const { return number_; }
|
||||
|
||||
private:
|
||||
int number_;
|
||||
};
|
||||
|
||||
int foo(int a1, A a2, const A &a3)
|
||||
{
|
||||
return a1 + a2.Get() + a3.Get();
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef Functor< int, TYPELIST_3(int, A, const A &) > func1_t;
|
||||
|
||||
func1_t fun1(foo);
|
||||
func1_t fun2(fun1);
|
||||
|
||||
A num1(10);
|
||||
printf("%d\n", fun1(1, num1, A(100)));
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER == 1300
|
||||
// will not compile with the original Loki although its fine
|
||||
printf("%d\n", BindFirst(fun2, 15)(A(24), num1));
|
||||
#else
|
||||
A num2(24);
|
||||
printf("%d\n", BindFirst(fun2, 15)(num2, num1)); // will not compile with the original loki
|
||||
#endif
|
||||
}
|
||||
|
||||
|
69
tools/RegressionTest/Test_HierarchyGenerators1.cpp
Normal file
69
tools/RegressionTest/Test_HierarchyGenerators1.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include "HierarchyGenerators.h"
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
//
|
||||
// Helper class for simulating (ranking) partial ordering
|
||||
//
|
||||
template<unsigned I>
|
||||
struct Order : Order<I - 1> {};
|
||||
|
||||
template<>
|
||||
struct Order<0> {};
|
||||
|
||||
template<template<typename> class Unit>
|
||||
class PrintGenScatterHierarchy
|
||||
{
|
||||
template<typename Head, typename Tail>
|
||||
PrintGenScatterHierarchy(GenScatterHierarchy<Typelist<Head, Tail>, Unit> *a, Order<1>)
|
||||
{
|
||||
printf("%s\n", typeid(*a).name());
|
||||
|
||||
GenScatterHierarchy<Head, Unit> *left = a;
|
||||
PrintGenScatterHierarchy<Unit> X1(left);
|
||||
|
||||
GenScatterHierarchy<Tail, Unit> *right = a;
|
||||
PrintGenScatterHierarchy<Unit> X2(right);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
PrintGenScatterHierarchy(GenScatterHierarchy<T, Unit> *a, Order<0>)
|
||||
{
|
||||
printf("%s\n", typeid(*a).name());
|
||||
|
||||
Unit<T> *left = a;
|
||||
(void)left;
|
||||
|
||||
printf("%s\n", typeid(*left).name());
|
||||
}
|
||||
|
||||
PrintGenScatterHierarchy(GenScatterHierarchy<NullType, Unit> *a, Order<1>)
|
||||
{
|
||||
(void)a;
|
||||
printf("%s\n", typeid(*a).name());
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
explicit PrintGenScatterHierarchy(GenScatterHierarchy<T, Unit> *a)
|
||||
{
|
||||
PrintGenScatterHierarchy<Unit>(a, Order<1>());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename> class TestUnit {};
|
||||
template<int> struct A {};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef TYPELIST_10(A<1>, A<2>, A<3>, A<4>, A<5>, A<6>, A<7>, A<8>, A<9>, A<10>) TestList_t;
|
||||
|
||||
GenScatterHierarchy<TestList_t, TestUnit> TestGenScatterHierarchy;
|
||||
|
||||
PrintGenScatterHierarchy<TestUnit> X(&TestGenScatterHierarchy);
|
||||
}
|
||||
|
||||
|
70
tools/RegressionTest/Test_HierarchyGenerators2.cpp
Normal file
70
tools/RegressionTest/Test_HierarchyGenerators2.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include "HierarchyGenerators.h"
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
//
|
||||
// Helper class for simulating (ranking) partial ordering
|
||||
//
|
||||
template<unsigned I>
|
||||
struct Order : Order<I - 1> {};
|
||||
|
||||
template<>
|
||||
struct Order<0> {};
|
||||
|
||||
template<template<typename, typename> class Unit, class Root>
|
||||
class PrintGenLinearHierarchy
|
||||
{
|
||||
template<typename Head>
|
||||
PrintGenLinearHierarchy(GenLinearHierarchy<Typelist<Head, NullType>, Unit, Root> *a, Order<1>)
|
||||
{
|
||||
printf("%s\n", typeid(*a).name());
|
||||
|
||||
Unit<Head, Root> *base1 = a;
|
||||
|
||||
printf("%s\n", typeid(*base1).name());
|
||||
|
||||
Root *base2 = base1; (void)base2;
|
||||
|
||||
printf("%s\n", typeid(*base2).name());
|
||||
}
|
||||
|
||||
template<typename Head, typename Tail>
|
||||
PrintGenLinearHierarchy(GenLinearHierarchy<Typelist<Head, Tail>, Unit, Root> *a, Order<0>)
|
||||
{
|
||||
printf("%s\n", typeid(*a).name());
|
||||
|
||||
Unit<Head, GenLinearHierarchy<Tail, Unit, Root> > *base1 = a;
|
||||
printf("%s\n", typeid(*base1).name());
|
||||
|
||||
GenLinearHierarchy<Tail, Unit, Root> *base2 = base1;
|
||||
PrintGenLinearHierarchy<Unit, Root> X(base2);
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename Head, typename Tail>
|
||||
explicit PrintGenLinearHierarchy(GenLinearHierarchy<Typelist<Head, Tail>, Unit, Root> *a)
|
||||
{
|
||||
PrintGenLinearHierarchy<Unit, Root>(a, Order<1>());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename, class Base>
|
||||
class TestUnit : public Base {};
|
||||
|
||||
class TestRoot {};
|
||||
|
||||
template<int> struct A {};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef TYPELIST_10(A<1>, A<2>, A<3>, A<4>, A<5>, A<6>, A<7>, A<8>, A<9>, A<10>) TestList_t;
|
||||
|
||||
GenLinearHierarchy<TestList_t, TestUnit, TestRoot> TestGenLinearHierarchy;
|
||||
|
||||
PrintGenLinearHierarchy<TestUnit, TestRoot> X(&TestGenLinearHierarchy);
|
||||
}
|
||||
|
||||
|
76
tools/RegressionTest/Test_HierarchyGenerators3.cpp
Normal file
76
tools/RegressionTest/Test_HierarchyGenerators3.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include "HierarchyGenerators.h"
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
//
|
||||
// Helper class for simulating (ranking) partial ordering
|
||||
//
|
||||
template<unsigned I>
|
||||
struct Order : Order<I - 1> {};
|
||||
|
||||
template<>
|
||||
struct Order<0> {};
|
||||
|
||||
template<template<typename> class Unit>
|
||||
class PrintGenScatterHierarchy
|
||||
{
|
||||
//
|
||||
// The second parameter is not needed when using compilers that support partial ordering
|
||||
// VC7 doesn't support that feature - this is an example of simulating that feature in VC7
|
||||
//
|
||||
template<typename Head, typename Tail>
|
||||
static void Print(GenScatterHierarchy<Typelist<Head, Tail>, Unit> &a, Order<1>)
|
||||
{
|
||||
printf("%s\n", typeid(a).name());
|
||||
|
||||
GenScatterHierarchy<Head, Unit> &left = a;
|
||||
Print(left);
|
||||
|
||||
GenScatterHierarchy<Tail, Unit> &right = a;
|
||||
Print(right);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void Print(GenScatterHierarchy<T, Unit> &a, Order<0>)
|
||||
{
|
||||
printf("%s\n", typeid(a).name());
|
||||
|
||||
Unit<T> &left = a;
|
||||
(void)left;
|
||||
|
||||
printf("%s\n", typeid(left).name());
|
||||
}
|
||||
|
||||
static void Print(GenScatterHierarchy<NullType, Unit> &a, Order<1>)
|
||||
{
|
||||
(void)a;
|
||||
printf("%s\n", typeid(a).name());
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename T>
|
||||
static void Print(GenScatterHierarchy<T, Unit> &a)
|
||||
{
|
||||
Print(a, Order<1>());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename> class TestUnit {};
|
||||
template<int> struct A {};
|
||||
template<int> struct B {};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef TYPELIST_20(A<1>, A<2>, A<3>, A<4>, A<5>, A<6>, A<7>, A<8>, A<9>, A<10>,
|
||||
B<1>, B<2>, B<3>, B<4>, B<5>, B<6>, B<7>, B<8>, B<9>, B<10>) TestList_t;
|
||||
|
||||
GenScatterHierarchy<TestList_t, TestUnit> TestGenScatterHierarchy;
|
||||
|
||||
PrintGenScatterHierarchy<TestUnit>::Print(TestGenScatterHierarchy);
|
||||
}
|
||||
|
||||
|
72
tools/RegressionTest/Test_HierarchyGenerators4.cpp
Normal file
72
tools/RegressionTest/Test_HierarchyGenerators4.cpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include "HierarchyGenerators.h"
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
//
|
||||
// Helper class for simulating (ranking) partial ordering
|
||||
//
|
||||
template<unsigned I>
|
||||
struct Order : Order<I - 1> {};
|
||||
|
||||
template<>
|
||||
struct Order<0> {};
|
||||
|
||||
template<template<typename, typename> class Unit, class Root>
|
||||
class PrintGenLinearHierarchy
|
||||
{
|
||||
template<typename Head, typename Tail>
|
||||
static void Print(GenLinearHierarchy<Typelist<Head, Tail>, Unit, Root> &a, Order<0>)
|
||||
{
|
||||
printf("%s\n", typeid(a).name());
|
||||
|
||||
Unit<Head, GenLinearHierarchy<Tail, Unit, Root> > &base1 = a;
|
||||
printf("%s\n", typeid(base1).name());
|
||||
|
||||
GenLinearHierarchy<Tail, Unit, Root> &base2 = base1;
|
||||
Print(base2);
|
||||
}
|
||||
|
||||
template<typename Head>
|
||||
static void Print(GenLinearHierarchy<Typelist<Head, NullType>, Unit, Root> &a, Order<1>)
|
||||
{
|
||||
printf("%s\n", typeid(a).name());
|
||||
|
||||
Unit<Head, Root> &base1 = a;
|
||||
|
||||
printf("%s\n", typeid(base1).name());
|
||||
|
||||
Root &base2 = base1; (void)base2;
|
||||
|
||||
printf("%s\n", typeid(base2).name());
|
||||
}
|
||||
|
||||
public:
|
||||
template<typename Head, typename Tail>
|
||||
static void Print(GenLinearHierarchy<Typelist<Head, Tail>, Unit, Root> &a)
|
||||
{
|
||||
Print(a, Order<1>());
|
||||
}
|
||||
};
|
||||
|
||||
template<typename, class Base>
|
||||
class TestUnit : public Base {};
|
||||
|
||||
class TestRoot {};
|
||||
|
||||
template<int> struct A {};
|
||||
template<int> struct B {};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef TYPELIST_20(A<1>, A<2>, A<3>, A<4>, A<5>, A<6>, A<7>, A<8>, A<9>, A<10>,
|
||||
B<1>, B<2>, B<3>, B<4>, B<5>, B<6>, B<7>, B<8>, B<9>, B<10>) TestList_t;
|
||||
|
||||
GenLinearHierarchy<TestList_t, TestUnit, TestRoot> TestGenLinearHierarchy;
|
||||
|
||||
PrintGenLinearHierarchy<TestUnit, TestRoot>::Print(TestGenLinearHierarchy);
|
||||
}
|
||||
|
||||
|
220
tools/RegressionTest/Test_MultiMethods.cpp
Normal file
220
tools/RegressionTest/Test_MultiMethods.cpp
Normal file
|
@ -0,0 +1,220 @@
|
|||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include "MultiMethods.h"
|
||||
|
||||
using ::std::cout;
|
||||
|
||||
struct Shape
|
||||
{
|
||||
virtual ~Shape() = 0;
|
||||
};
|
||||
|
||||
Shape::~Shape() {}
|
||||
|
||||
class Rectangle : public Shape {};
|
||||
class Poly : public Shape {};
|
||||
class Ellipse : public Shape {};
|
||||
class Cycloid : public Shape {};
|
||||
|
||||
class SymHachingExecutor
|
||||
{
|
||||
public:
|
||||
typedef void ResultType;
|
||||
|
||||
ResultType Fire(Rectangle&, Rectangle&)
|
||||
{ cout << "Fire(Rectangle&, Rectangle&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Rectangle&, Poly&)
|
||||
{ cout << "Fire(Rectangle&, Poly&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Rectangle&, Ellipse&)
|
||||
{ cout << "Fire(Rectangle&, Ellipse&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Poly&, Poly&)
|
||||
{ cout << "Fire(Poly&, Poly&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Poly&, Ellipse&)
|
||||
{ cout << "Fire(Poly&, Ellipse&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Ellipse&, Ellipse&)
|
||||
{ cout << "Fire(Ellipse&, Ellipse&)" << '\n'; }
|
||||
|
||||
void OnError(Shape& x, Shape& y)
|
||||
{
|
||||
cout << "OnError: "
|
||||
<< typeid(x).name() << ", "
|
||||
<< typeid(y).name() << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
typedef ::Loki::StaticDispatcher
|
||||
<
|
||||
SymHachingExecutor,
|
||||
Shape,
|
||||
TYPELIST_3(Rectangle, Poly, Ellipse)
|
||||
>
|
||||
SymHachingDispatcher;
|
||||
|
||||
|
||||
class HachingExecutor : SymHachingExecutor
|
||||
{
|
||||
public:
|
||||
typedef SymHachingExecutor::ResultType ResultType;
|
||||
|
||||
using SymHachingExecutor::Fire;
|
||||
|
||||
ResultType Fire(Poly&, Rectangle&)
|
||||
{ cout << "Fire(Poly&, Rectangle&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Ellipse&, Rectangle&)
|
||||
{ cout << "Fire(Ellipse&, Rectangle&)" << '\n'; }
|
||||
|
||||
ResultType Fire(Ellipse&, Poly&)
|
||||
{ cout << "Fire(Ellipse&, Poly&)" << '\n'; }
|
||||
|
||||
using SymHachingExecutor::OnError;
|
||||
};
|
||||
|
||||
typedef ::Loki::StaticDispatcher
|
||||
<
|
||||
HachingExecutor,
|
||||
Shape,
|
||||
TYPELIST_3(Rectangle, Poly, Ellipse),
|
||||
false
|
||||
>
|
||||
HachingDispatcher;
|
||||
|
||||
template<class TestedHachingDispatcher, class TestedHachingExecutor>
|
||||
void Test_HachingDispatcher(TestedHachingExecutor Exec)
|
||||
{
|
||||
using ::std::auto_ptr;
|
||||
|
||||
auto_ptr<Shape> shape1(new Rectangle);
|
||||
auto_ptr<Shape> shape2(new Ellipse);
|
||||
auto_ptr<Shape> shape3(new Poly);
|
||||
auto_ptr<Shape> shape4(new Cycloid);
|
||||
|
||||
static const std::size_t number_of_shapes = 4;
|
||||
|
||||
Shape * const shapes[number_of_shapes] =
|
||||
{
|
||||
shape1.get(), shape2.get(),
|
||||
shape3.get(), shape4.get(),
|
||||
};
|
||||
|
||||
for (std::size_t i = 0 ; i < number_of_shapes ; ++i)
|
||||
for (std::size_t j = 0 ; j < number_of_shapes ; ++j)
|
||||
{
|
||||
TestedHachingDispatcher::Go(*shapes[i], *shapes[j], Exec);
|
||||
}
|
||||
}
|
||||
|
||||
typedef ::Loki::BasicDispatcher<Shape> ShapeBasicDispatcher;
|
||||
typedef ::Loki::FnDispatcher<Shape> ShapeFnDispatcher;
|
||||
typedef ::Loki::FunctorDispatcher<Shape> ShapeFunctorDispatcher;
|
||||
|
||||
namespace // anonymous
|
||||
{
|
||||
template<class Shape1, class Shape2>
|
||||
void HatchShapesDo(Shape1 &, Shape2 &)
|
||||
{
|
||||
cout << "HatchShapes: "
|
||||
<< typeid(Shape1).name() << ", "
|
||||
<< typeid(Shape2).name() << '\n';
|
||||
}
|
||||
|
||||
template<class Shape1, class Shape2>
|
||||
void HatchShapes(Shape &lhs, Shape &rhs)
|
||||
{
|
||||
assert(dynamic_cast<Shape1*>(&lhs) != 0);
|
||||
assert(dynamic_cast<Shape2*>(&rhs) != 0);
|
||||
|
||||
HatchShapesDo(static_cast<Shape1&>(lhs),
|
||||
static_cast<Shape2&>(rhs));
|
||||
}
|
||||
|
||||
template<class Shape1, class Shape2>
|
||||
struct HatchShapesFunctor
|
||||
{
|
||||
void operator()(Shape1 &lhs, Shape2 &rhs)
|
||||
{
|
||||
HatchShapesDo(lhs, rhs);
|
||||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
template<class Shape1, class Shape2>
|
||||
void ShapeDispatcherAdd(ShapeBasicDispatcher &x)
|
||||
{
|
||||
x.Add<Shape1, Shape2>(HatchShapes<Shape1, Shape2>);
|
||||
}
|
||||
|
||||
template<class Shape1, class Shape2>
|
||||
void ShapeDispatcherAdd(ShapeFnDispatcher &x)
|
||||
{
|
||||
x.Add<Shape1, Shape2>(HatchShapes<Shape1, Shape2>);
|
||||
}
|
||||
|
||||
template<class Shape1, class Shape2>
|
||||
void ShapeDispatcherAdd(ShapeFunctorDispatcher &x)
|
||||
{
|
||||
x.Add<Shape1, Shape2>(HatchShapesFunctor<Shape1, Shape2>());
|
||||
}
|
||||
|
||||
template<class Dispacher>
|
||||
void Test_LogDispacher()
|
||||
{
|
||||
Dispacher testedBasicDispatcher;
|
||||
|
||||
ShapeDispatcherAdd<Rectangle, Poly>(testedBasicDispatcher);
|
||||
ShapeDispatcherAdd<Poly, Rectangle>(testedBasicDispatcher);
|
||||
ShapeDispatcherAdd<Rectangle, Ellipse>(testedBasicDispatcher);
|
||||
ShapeDispatcherAdd<Ellipse, Poly>(testedBasicDispatcher);
|
||||
ShapeDispatcherAdd<Poly, Poly>(testedBasicDispatcher);
|
||||
|
||||
|
||||
using ::std::auto_ptr;
|
||||
|
||||
auto_ptr<Shape> shape1(new Rectangle);
|
||||
auto_ptr<Shape> shape2(new Ellipse);
|
||||
auto_ptr<Shape> shape3(new Poly);
|
||||
|
||||
static const std::size_t number_of_shapes = 3;
|
||||
|
||||
Shape * const shapes[number_of_shapes] =
|
||||
{
|
||||
shape1.get(), shape2.get(), shape3.get(),
|
||||
};
|
||||
|
||||
for (std::size_t i = 0 ; i < number_of_shapes ; ++i)
|
||||
for (std::size_t j = 0 ; j < number_of_shapes ; ++j)
|
||||
{
|
||||
try
|
||||
{
|
||||
testedBasicDispatcher.Go(*shapes[i], *shapes[j]);
|
||||
}
|
||||
catch(::std::runtime_error &exp)
|
||||
{
|
||||
cout << exp.what() << ": "
|
||||
<< typeid(*shapes[i]).name() << ", "
|
||||
<< typeid(*shapes[j]).name() << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SymHachingExecutor SymExec;
|
||||
Test_HachingDispatcher<SymHachingDispatcher>(SymExec);
|
||||
|
||||
HachingExecutor Exec;
|
||||
Test_HachingDispatcher<HachingDispatcher>(Exec);
|
||||
|
||||
Test_LogDispacher<ShapeBasicDispatcher>();
|
||||
Test_LogDispacher<ShapeFnDispatcher>();
|
||||
Test_LogDispacher<ShapeFunctorDispatcher>();
|
||||
}
|
||||
|
34
tools/RegressionTest/Test_Singleton.cpp
Normal file
34
tools/RegressionTest/Test_Singleton.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
#include <Loki\Singleton.h>
|
||||
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
struct A { ~A(){} };
|
||||
struct B { ~B(){} };
|
||||
struct C { ~C(){} };
|
||||
|
||||
unsigned int GetLongevity(C*)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}//ns anon
|
||||
|
||||
extern void Test_Singleton()
|
||||
{
|
||||
cout << "Testing Loki\\Singleton" << endl;
|
||||
typedef SingletonHolder<A> SingletonHolder1_t;
|
||||
typedef SingletonHolder<B, CreateStatic> SingletonHolder2_t;
|
||||
typedef SingletonHolder<C, CreateUsingNew, SingletonWithLongevity> SingletonHolder3_t;
|
||||
|
||||
A& p = SingletonHolder1_t::Instance();
|
||||
SingletonHolder2_t::Instance();
|
||||
SingletonHolder3_t::Instance();
|
||||
cout << endl << endl;
|
||||
}
|
||||
|
22
tools/RegressionTest/Test_SmallObj.cpp
Normal file
22
tools/RegressionTest/Test_SmallObj.cpp
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
//Test the Small Object Allocator
|
||||
// MKH
|
||||
//
|
||||
|
||||
#include <Loki\SmallObj.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Test : Loki::SmallObj
|
||||
{
|
||||
};
|
||||
void Test_SmallObject()
|
||||
{
|
||||
Test;
|
||||
}
|
||||
}//ns anon
|
||||
|
||||
extern void Test_SmallObj()
|
||||
{
|
||||
Test_SmallObject();
|
||||
}
|
286
tools/RegressionTest/Test_SmartPtr.cpp
Normal file
286
tools/RegressionTest/Test_SmartPtr.cpp
Normal file
|
@ -0,0 +1,286 @@
|
|||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <Loki\SmartPtr.h>
|
||||
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
#if defined(TEST_LOKI_ORIG)
|
||||
namespace Loki
|
||||
{
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
template <class> class OwnershipPolicy = RefCounted,
|
||||
class ConversionPolicy = DisallowConversion,
|
||||
template <class> class CheckingPolicy = AssertCheck,
|
||||
template <class> class StoragePolicy = DefaultSPStorage
|
||||
>
|
||||
struct SmartPtrDef
|
||||
{
|
||||
typedef SmartPtr
|
||||
<
|
||||
T,
|
||||
OwnershipPolicy,
|
||||
ConversionPolicy,
|
||||
CheckingPolicy,
|
||||
StoragePolicy
|
||||
>
|
||||
type;
|
||||
};
|
||||
} // namespace Loki
|
||||
#endif // defined(TEST_LOKI_ORIG)
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
namespace
|
||||
{
|
||||
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<class SmartPtr_A>
|
||||
struct PrintA
|
||||
{
|
||||
void operator()(const SmartPtr_A &spA) const
|
||||
{
|
||||
std::cout << spA->name() << ", ";
|
||||
}
|
||||
};
|
||||
|
||||
void Test_SmartPointer()
|
||||
{
|
||||
typedef SmartPtrDef<A, RefCounted>::type SmartPtr_A;
|
||||
typedef SmartPtrDef<B, RefCounted>::type SmartPtr_B;
|
||||
typedef SmartPtrDef<C, RefCounted>::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<SmartPtr_A> 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<SmartPtr_A>());
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// I know it's ugly code duplication but the template version kills VC7
|
||||
void Test_SmartPtrRL()
|
||||
{
|
||||
typedef SmartPtrDef<A, RefLinked>::type SmartPtr_A;
|
||||
typedef SmartPtrDef<B, RefLinked>::type SmartPtr_B;
|
||||
typedef SmartPtrDef<C, RefLinked>::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<SmartPtr_A> 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<SmartPtr_A>());
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void Test_SmartPtrMT()
|
||||
{
|
||||
#define MyRefCountedMT RefCountedMTAdj<SingleThreaded>::RefCountedMT
|
||||
|
||||
typedef SmartPtrDef<A, MyRefCountedMT>::type SmartPtr_A;
|
||||
typedef SmartPtrDef<B, MyRefCountedMT>::type SmartPtr_B;
|
||||
typedef SmartPtrDef<C, MyRefCountedMT>::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<SmartPtr_A> 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<SmartPtr_A>());
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void Test_RejectNull()
|
||||
{
|
||||
typedef SmartPtrDef<A, RefCounted, DisallowConversion, RejectNull>::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;
|
||||
}
|
||||
}
|
||||
|
||||
}// anonymous namespace
|
||||
|
||||
extern void Test_SmartPtr()
|
||||
{
|
||||
cout << "Testing Loki\\SmartPtr" << endl;
|
||||
Test_SmartPointer();
|
||||
Test_SmartPtrRL();
|
||||
Test_SmartPtrMT();
|
||||
Test_RejectNull();
|
||||
A::AssertInstCount();
|
||||
cout << endl << endl;
|
||||
}
|
||||
|
145
tools/RegressionTest/Test_SmartPtrWin.cpp
Normal file
145
tools/RegressionTest/Test_SmartPtrWin.cpp
Normal file
|
@ -0,0 +1,145 @@
|
|||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "SmartPtr.h"
|
||||
|
||||
#if defined(TEST_LOKI_ORIG)
|
||||
namespace Loki
|
||||
{
|
||||
template
|
||||
<
|
||||
typename T,
|
||||
template <class> class OwnershipPolicy = RefCounted,
|
||||
class ConversionPolicy = DisallowConversion,
|
||||
template <class> class CheckingPolicy = AssertCheck,
|
||||
template <class> 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<class SmartPtr_A>
|
||||
struct PrintA
|
||||
{
|
||||
void operator()(const SmartPtr_A &spA) const
|
||||
{
|
||||
std::cout << spA->name() << ", ";
|
||||
}
|
||||
};
|
||||
|
||||
void Test_SmartPtr()
|
||||
{
|
||||
#define MyRefCountedMT RefCountedMTAdj<ObjectLevelLockable>::RefCountedMT
|
||||
//#define MyRefCountedMT RefCountedMTAdj<ClassLevelLockable>::RefCountedMT
|
||||
|
||||
typedef SmartPtrDef<A, MyRefCountedMT>::type SmartPtr_A;
|
||||
typedef SmartPtrDef<B, MyRefCountedMT>::type SmartPtr_B;
|
||||
typedef SmartPtrDef<C, MyRefCountedMT>::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<SmartPtr_A> 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<SmartPtr_A>());
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Test_SmartPtr();
|
||||
A::AssertInstCount();
|
||||
}
|
||||
|
21
tools/RegressionTest/Test_Threads.cpp
Normal file
21
tools/RegressionTest/Test_Threads.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
//Test the Thread components
|
||||
// MKH
|
||||
|
||||
#include <Loki\Threads.h>
|
||||
using namespace ::Loki;
|
||||
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
namespace
|
||||
{
|
||||
}
|
||||
|
||||
extern void Test_Threads()
|
||||
{
|
||||
cout << "Testing Loki\\Threads" << endl;
|
||||
SingleThreaded<void>();
|
||||
cout << endl << endl;
|
||||
}
|
70
tools/RegressionTest/Test_Tuple.cpp
Normal file
70
tools/RegressionTest/Test_Tuple.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include "HierarchyGenerators.h"
|
||||
|
||||
using namespace Loki;
|
||||
|
||||
template<typename T>
|
||||
void PrintType(T &)
|
||||
{
|
||||
printf("%s\n", typeid(T).name());
|
||||
}
|
||||
|
||||
template<unsigned I>
|
||||
class PrintTuple
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
explicit PrintTuple(const T &x)
|
||||
{
|
||||
PrintTuple<I - 1> X(x);
|
||||
PrintType(Field<I>(x));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
class PrintTuple<0>
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
explicit PrintTuple(const T &x)
|
||||
{
|
||||
PrintType(Field<0>(x));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
void PrintTupleFunc()
|
||||
{
|
||||
T x;
|
||||
|
||||
PrintTuple<TL::Length<typename T::TList>::value - 1> X(x);
|
||||
}
|
||||
|
||||
template<int> struct A {};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef TYPELIST_11(A<1>, A<1>, int, int, A<1>, A<2>, int[10], int, int *, A<2>, A<3>) typelist_t;
|
||||
typedef Tuple<typelist_t> tuple_t;
|
||||
|
||||
PrintTupleFunc<tuple_t>();
|
||||
|
||||
tuple_t X;
|
||||
A<3> Y = Field< A<3> >(X);
|
||||
|
||||
// without -Za warning C4239: nonstandard extension used
|
||||
// this is because VC sometimes binds temporary to non-const reference
|
||||
// which leads to selecting the wrong Field function (non-const version)
|
||||
// fixed in VC7.1
|
||||
Y = Field< A<3> >(tuple_t());
|
||||
|
||||
A<3> &Y1 = Field< A<3> >(X);
|
||||
Y1 = Y;
|
||||
}
|
||||
|
||||
|
223
tools/RegressionTest/Test_TypeList.cpp
Normal file
223
tools/RegressionTest/Test_TypeList.cpp
Normal file
|
@ -0,0 +1,223 @@
|
|||
#include <cstdio>
|
||||
#include <typeinfo>
|
||||
#include <Loki\Typelist.h>
|
||||
#include <iostream>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
namespace
|
||||
{
|
||||
typedef struct IncompType *IncompPtr;
|
||||
|
||||
struct A1 {};
|
||||
struct B1 : A1 {};
|
||||
|
||||
struct A2 {};
|
||||
struct B2 : A2 {};
|
||||
|
||||
struct C1 : B1 {};
|
||||
struct C2 : B2 {};
|
||||
struct D1 : C1, C2 {};
|
||||
|
||||
template<typename TList>
|
||||
struct PrintTypelist
|
||||
{
|
||||
PrintTypelist()
|
||||
{
|
||||
typedef typename TList::Head Head;
|
||||
typedef typename TList::Tail Tail;
|
||||
|
||||
printf("%s ,", typeid(Head).name());
|
||||
|
||||
PrintTypelist<Tail>();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PrintTypelist<NullType>
|
||||
{
|
||||
PrintTypelist()
|
||||
{
|
||||
printf("\n");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Test_Length()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, int, B2*, B2 const *, B1>::Result typelist_t;
|
||||
|
||||
printf("%u\n", TL::Length<typelist_t>::value);
|
||||
}
|
||||
|
||||
|
||||
void Test_TypeAt()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, int>::Result typelist_t;
|
||||
|
||||
printf("%s, ", typeid(TL::TypeAt<typelist_t, 0>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAt<typelist_t, 1>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAt<typelist_t, 2>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAt<typelist_t, 3>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAt<typelist_t, 4>::Result).name());
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void Test_IndexOf()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, int, B2*, B2 const *, B1>::Result typelist_t;
|
||||
|
||||
printf("%u, ", TL::IndexOf<typelist_t, IncompPtr>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, B1>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, B2*>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, A2**>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, int>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, B2 const *>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, const B1>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, B1&>::value);
|
||||
printf("%u, ", TL::IndexOf<typelist_t, int const &>::value);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void Test_TypeAtNonStrict()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, int>::Result typelist_t;
|
||||
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 0>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 1>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 2, double>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 3>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 4>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 5>::Result).name());
|
||||
printf("%s, ", typeid(TL::TypeAtNonStrict<typelist_t, 9, void>::Result).name());
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void Test_Append()
|
||||
{
|
||||
typedef TL::MakeTypeList<int, A1, A2>::Result typelist1_t;
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**>::Result typelist2_t;
|
||||
|
||||
PrintTypelist<TL::Append<NullType, NullType>::Result>();
|
||||
PrintTypelist<TL::Append<NullType, typelist2_t>::Result>();
|
||||
PrintTypelist<TL::Append<typelist1_t, NullType>::Result>();
|
||||
PrintTypelist<TL::Append<NullType, int>::Result>();
|
||||
PrintTypelist<TL::Append<typelist1_t, int[10]>::Result>();
|
||||
PrintTypelist<TL::Append<typelist1_t, typelist2_t>::Result>();
|
||||
}
|
||||
|
||||
void Test_Erase()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B1>::Result typelist_t;
|
||||
|
||||
PrintTypelist<TL::Erase<typelist_t, int>::Result>();
|
||||
PrintTypelist<TL::Erase<typelist_t, B1>::Result>();
|
||||
PrintTypelist<TL::Erase<typelist_t, B2>::Result>();
|
||||
PrintTypelist<TL::Erase<typelist_t, const B1>::Result>();
|
||||
PrintTypelist<TL::Erase<typelist_t, B2 const *>::Result>();
|
||||
PrintTypelist<TL::Erase<typelist_t, A2**>::Result>();
|
||||
PrintTypelist<TL::Erase<typelist_t, NullType>::Result>();
|
||||
}
|
||||
|
||||
void Test_EraseAll()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B1, B2*, B2 const *, B1>::Result typelist_t;
|
||||
|
||||
PrintTypelist<TL::EraseAll<typelist_t, int>::Result>();
|
||||
PrintTypelist<TL::EraseAll<typelist_t, B1>::Result>();
|
||||
PrintTypelist<TL::EraseAll<typelist_t, B2*>::Result>();
|
||||
PrintTypelist<TL::EraseAll<typelist_t, B2 const *>::Result>();
|
||||
PrintTypelist<TL::EraseAll<typelist_t, NullType>::Result>();
|
||||
}
|
||||
|
||||
void Test_NoDuplicates()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B1, B2*, B2 const *, B1>::Result typelist1_t;
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B2 const *>::Result typelist2_t;
|
||||
|
||||
PrintTypelist<TL::NoDuplicates<typelist1_t>::Result>();
|
||||
PrintTypelist<TL::NoDuplicates<typelist2_t>::Result>();
|
||||
}
|
||||
|
||||
void Test_Replace()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B1, B2*, B2 const *, B1>::Result typelist1_t;
|
||||
|
||||
PrintTypelist<TL::Replace<typelist1_t, int, A1>::Result>();
|
||||
PrintTypelist<TL::Replace<typelist1_t, B1, int>::Result>();
|
||||
PrintTypelist<TL::Replace<typelist1_t, B2*, B2[1]>::Result>();
|
||||
}
|
||||
|
||||
void Test_ReplaceAll()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B1, B2*, B2 const *, B1>::Result typelist1_t;
|
||||
|
||||
PrintTypelist<TL::ReplaceAll<typelist1_t, int, A1>::Result>();
|
||||
PrintTypelist<TL::ReplaceAll<typelist1_t, B1, int>::Result>();
|
||||
PrintTypelist<TL::ReplaceAll<typelist1_t, B2*, B2[1]>::Result>();
|
||||
}
|
||||
|
||||
void Test_Reverse()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2**, B1, B2*, B2 const *, B1>::Result typelist1_t;
|
||||
|
||||
PrintTypelist<TL::Reverse<typelist1_t>::Result>();
|
||||
}
|
||||
|
||||
void Test_MostDerived()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2*, A2, C1, B1, B2*, B2 const *, B1>::Result typelist1_t;
|
||||
|
||||
printf("%s, ", typeid(TL::MostDerived<typelist1_t, A2>::Result).name());
|
||||
printf("%s, ", typeid(TL::MostDerived<typelist1_t, A1>::Result).name());
|
||||
printf("%s, ", typeid(TL::MostDerived<typelist1_t, B1>::Result).name());
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void Test_DerivedToFront()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2, A2, C1, B1, C2, D1, B2, A1, B1, A1>::Result typelist1_t;
|
||||
typedef TL::MakeTypeList<B1, A1, C1>::Result typelist2_t;
|
||||
|
||||
PrintTypelist<TL::DerivedToFront<typelist1_t>::Result>();
|
||||
PrintTypelist<TL::DerivedToFront<typelist2_t>::Result>();
|
||||
}
|
||||
|
||||
void Test_DerivedToFrontAll()
|
||||
{
|
||||
typedef TL::MakeTypeList<IncompPtr, B1, B2, A2, C1, B1, C2, D1, B2, A1, B1, A1>::Result typelist1_t;
|
||||
typedef TL::MakeTypeList<B1, A1, C1>::Result typelist2_t;
|
||||
|
||||
PrintTypelist<TL::DerivedToFrontAll<typelist1_t>::Result>();
|
||||
PrintTypelist<TL::DerivedToFrontAll<typelist2_t>::Result>();
|
||||
}
|
||||
|
||||
}// anon namespace
|
||||
|
||||
extern void Test_TypeList()
|
||||
{
|
||||
cout << "Testing Loki::TypeList" << endl;
|
||||
Test_Length();
|
||||
Test_TypeAt();
|
||||
Test_TypeAtNonStrict();
|
||||
Test_IndexOf();
|
||||
Test_Append();
|
||||
Test_Erase();
|
||||
Test_EraseAll();
|
||||
Test_NoDuplicates();
|
||||
Test_Replace();
|
||||
Test_ReplaceAll();
|
||||
Test_Reverse();
|
||||
Test_MostDerived();
|
||||
Test_DerivedToFront();
|
||||
Test_DerivedToFrontAll();
|
||||
cout << endl << endl;
|
||||
}
|
||||
|
||||
|
95
tools/RegressionTest/Test_Variant.cpp
Normal file
95
tools/RegressionTest/Test_Variant.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#if defined(_MSC_VER) && _MSC_VER >= 1300
|
||||
#pragma warning (disable : 4503 4244)
|
||||
#endif
|
||||
|
||||
// 4503: decorated name length exceeded, name was truncated
|
||||
// 4244: 'argument' : conversion from '<tyep1>' to '<type2>', possible loss of data
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include "Variant.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
try
|
||||
{
|
||||
typedef Variant<TYPELIST_3(string, int, double)> DBField;
|
||||
|
||||
DBField fld1(string("Hello, world"));
|
||||
DBField fld2(25);
|
||||
DBField fld3(3.14);
|
||||
|
||||
assert(fld1.TypeId() == typeid(string));
|
||||
assert(fld2.TypeId() == typeid(int));
|
||||
|
||||
string* p = fld1.GetPtr<string>();
|
||||
assert(p != 0);
|
||||
*p += '!';
|
||||
assert(fld1.Get<std::string>() == "Hello, world!");
|
||||
|
||||
fld3 = fld1;
|
||||
assert(fld1.Get<std::string>() == "Hello, world!");
|
||||
assert(fld3.Get<std::string>() == "Hello, world!");
|
||||
|
||||
fld3 = std::string("Assignment");
|
||||
assert(fld3.Get<std::string>() == "Assignment");
|
||||
|
||||
DBField fld5;
|
||||
|
||||
assert(fld5.TypeId() == typeid(string));
|
||||
assert(fld5.GetPtr<string>()->empty());
|
||||
|
||||
DBField fld4 = fld1;
|
||||
assert(fld4.TypeId() == typeid(string));
|
||||
assert(fld4.Get<std::string>() == "Hello, world!");
|
||||
|
||||
DBField fld(45);
|
||||
float f = fld.ConvertTo<float>();
|
||||
assert(f == 45);
|
||||
(void)f;
|
||||
|
||||
fld2.ChangeType<double>();
|
||||
assert(fld2.Get<double>() == 25);
|
||||
|
||||
typedef Variant<TYPELIST_3(string, int, float)> AlternateDBField;
|
||||
AlternateDBField fld6(fld1);
|
||||
assert(fld6.Get<std::string>() == "Hello, world!");
|
||||
|
||||
fld6 = fld3;
|
||||
assert(fld6.Get<std::string>() == "Assignment");
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1300
|
||||
//
|
||||
// Variant with VC non-standard alignment support
|
||||
//
|
||||
typedef TYPELIST_3(string, double, int) DBField2Typelist;
|
||||
typedef Variant<DBField2Typelist, VC_AlignedPOD<DBField2Typelist> > AlternateDBField2;
|
||||
|
||||
AlternateDBField2 fld7(fld6);
|
||||
assert(fld7.Get<std::string>() == "Assignment");
|
||||
|
||||
fld7 = fld2;
|
||||
assert(fld7.Get<double>() == 25.0);
|
||||
|
||||
enum {
|
||||
OrigAlign = __alignof(fld1),
|
||||
VCExAlign = __alignof(fld7)
|
||||
};
|
||||
|
||||
STATIC_CHECK(OrigAlign == VCExAlign, WrongAlignment);
|
||||
|
||||
#endif // def _MSC_VER
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
cout << "Something weird happened: " << e.what();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
cout << "Something really weird happened.";
|
||||
}
|
||||
}
|
||||
|
158
tools/RegressionTest/Test_Visitor.cpp
Normal file
158
tools/RegressionTest/Test_Visitor.cpp
Normal file
|
@ -0,0 +1,158 @@
|
|||
#include <iostream>
|
||||
#include "Visitor.h"
|
||||
|
||||
using namespace ::Loki;
|
||||
|
||||
class RasterBitmap
|
||||
: public BaseVisitable<>
|
||||
{
|
||||
public:
|
||||
DEFINE_VISITABLE()
|
||||
};
|
||||
|
||||
class Paragraph
|
||||
: public BaseVisitable<>
|
||||
{
|
||||
public:
|
||||
DEFINE_VISITABLE()
|
||||
};
|
||||
|
||||
|
||||
class ParagraphEx
|
||||
: public Paragraph
|
||||
{
|
||||
public:
|
||||
DEFINE_VISITABLE()
|
||||
};
|
||||
|
||||
class DummyParagraph
|
||||
: public Paragraph
|
||||
{
|
||||
public:
|
||||
DEFINE_VISITABLE()
|
||||
};
|
||||
|
||||
class DummyRasterBitmap
|
||||
: public RasterBitmap
|
||||
{
|
||||
public:
|
||||
DEFINE_VISITABLE()
|
||||
};
|
||||
|
||||
class SomeVisitor
|
||||
: public BaseVisitor
|
||||
, public Visitor<TYPELIST_3(RasterBitmap, Paragraph, ParagraphEx)>
|
||||
, public BaseVisitorImpl<TYPELIST_2(DummyParagraph, DummyRasterBitmap)>
|
||||
{
|
||||
public:
|
||||
void Visit(RasterBitmap&)
|
||||
{
|
||||
std::cout << "SomeVisitor::Visit(RasterBitmap&)" << '\n';
|
||||
}
|
||||
|
||||
void Visit(Paragraph &)
|
||||
{
|
||||
std::cout << "SomeVisitor::Visit(Paragraph&)" << '\n';
|
||||
}
|
||||
|
||||
void Visit(ParagraphEx &)
|
||||
{
|
||||
std::cout << "SomeVisitor::Visit(ParagraphEx&)" << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Test_Visitor()
|
||||
{
|
||||
SomeVisitor someVisit;
|
||||
BaseVisitor &baseVisit = someVisit;
|
||||
|
||||
RasterBitmap rast;
|
||||
rast.Accept(baseVisit);
|
||||
|
||||
Paragraph par;
|
||||
par.Accept(baseVisit);
|
||||
|
||||
ParagraphEx parEx;
|
||||
parEx.Accept(baseVisit);
|
||||
|
||||
DummyRasterBitmap dummyRast;
|
||||
dummyRast.Accept(baseVisit);
|
||||
|
||||
DummyParagraph dummyPar;
|
||||
dummyPar.Accept(baseVisit);
|
||||
}
|
||||
|
||||
typedef CyclicVisitor
|
||||
<
|
||||
void,
|
||||
TYPELIST_3(class DocElement, class RasterBitmap2, class Paragraph2)
|
||||
>
|
||||
MyCyclicVisitor;
|
||||
|
||||
|
||||
class DocElement
|
||||
{
|
||||
public:
|
||||
virtual void Accept(MyCyclicVisitor &) = 0;
|
||||
virtual ~DocElement() {}
|
||||
};
|
||||
|
||||
class RasterBitmap2
|
||||
: public DocElement
|
||||
{
|
||||
public:
|
||||
DEFINE_CYCLIC_VISITABLE(MyCyclicVisitor)
|
||||
};
|
||||
|
||||
class Paragraph2
|
||||
: public DocElement
|
||||
{
|
||||
public:
|
||||
DEFINE_CYCLIC_VISITABLE(MyCyclicVisitor)
|
||||
};
|
||||
|
||||
class SomeVisitor2
|
||||
: public MyCyclicVisitor
|
||||
{
|
||||
public:
|
||||
void Visit(DocElement &)
|
||||
{
|
||||
std::cout << "SomeVisitor::Visit(DocElement&)" << '\n';
|
||||
}
|
||||
|
||||
void Visit(Paragraph2 &)
|
||||
{
|
||||
std::cout << "SomeVisitor::Visit(Paragraph2&)" << '\n';
|
||||
}
|
||||
|
||||
void Visit(RasterBitmap2 &)
|
||||
{
|
||||
std::cout << "SomeVisitor::Visit(RasterBitmap2&)" << '\n';
|
||||
}
|
||||
};
|
||||
|
||||
void Test_CyclicVisitor()
|
||||
{
|
||||
SomeVisitor2 someVisit;
|
||||
MyCyclicVisitor &baseVisit = someVisit;
|
||||
|
||||
RasterBitmap2 rast;
|
||||
rast.Accept(baseVisit);
|
||||
|
||||
Paragraph2 par;
|
||||
par.Accept(baseVisit);
|
||||
|
||||
DocElement &docElem1 = par;
|
||||
docElem1.Accept(baseVisit);
|
||||
|
||||
DocElement &docElem2 = rast;
|
||||
docElem2.Accept(baseVisit);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
Test_Visitor();
|
||||
Test_CyclicVisitor();
|
||||
}
|
||||
|
Loading…
Reference in a new issue