diff --git a/tools/RegressionTest/AllTest/AllTest.cpp b/tools/RegressionTest/AllTest/AllTest.cpp new file mode 100644 index 0000000..39d83ac --- /dev/null +++ b/tools/RegressionTest/AllTest/AllTest.cpp @@ -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 + +int main() + { + Test_TypeList(); + Test_SmartPtr(); + Test_Singleton(); + Test_Threads(); + /*Test_SmallObj(); + Test_Functor(); + */ + + /*Test_ObjectFactory(); + Test_AbstractFactory(); + Test_Vistor(); + Test_MultiMethods(); + */ + system("pause"); + }; \ No newline at end of file diff --git a/tools/RegressionTest/LokiRegressionTest.vcproj b/tools/RegressionTest/AllTest/AllTest.vcproj similarity index 67% rename from tools/RegressionTest/LokiRegressionTest.vcproj rename to tools/RegressionTest/AllTest/AllTest.vcproj index cf9a2a5..1a79c51 100644 --- a/tools/RegressionTest/LokiRegressionTest.vcproj +++ b/tools/RegressionTest/AllTest/AllTest.vcproj @@ -2,8 +2,8 @@ + RelativePath="AllTest.cpp"> + RelativePath="..\Test_Singleton.cpp"> + RelativePath="..\Test_SmartPtr.cpp"> - - - - + RelativePath="..\Test_Threads.cpp"> + RelativePath="..\Test_TypeList.cpp"> - - - - + RelativePath="..\..\..\Singleton.cpp"> - - - - - - + RelativePath="..\..\..\SmallObj.cpp"> - - diff --git a/tools/RegressionTest/LokiTest.cpp b/tools/RegressionTest/LokiTest.cpp deleted file mode 100644 index 4f37ed9..0000000 --- a/tools/RegressionTest/LokiTest.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// LokiTest.cpp : Defines the entry point for the console application. -// - -#include -#include -#include -#include -#include - -//#define LOKI_USE_REFERENCE - -#include -#include -#include -#include -#include -#include - -//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"<, Loki::RegressionTest::Complex, void, int, double) tyList5; - } - } -#endif \ No newline at end of file diff --git a/tools/RegressionTest/LokiTest_TypeInfo.h b/tools/RegressionTest/LokiTest_TypeInfo.h deleted file mode 100644 index 1b36a3a..0000000 --- a/tools/RegressionTest/LokiTest_TypeInfo.h +++ /dev/null @@ -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"<::value<::value<::value<::value==1) &&\ - (Loki::TL::Length::value==2) &&\ - (Loki::TL::Length::value==5) )\ - cout<<"Normal cases work"<::value<::value<::value==0) &&\ - (Loki::TL::Length::value==0) )\ - cout<<"Pathological cases work"<::Result FailsToCompile; - typedef TypeAt::Result FirstType; - typedef TypeAt::Result SecondType; - typedef TypeAt::Result ThirdType; - typedef TypeAt::Result FourthType; - typedef TypeAt::Result FifthType; - cout<::value<::value< >::value<::value<::value<::Result List0; - typedef Append::Result List1; - typedef Append::Result List2; - typedef Append:: Result List3; - cout << Length::value << endl; - cout << Length::value << "\t"; - cout << typeid(TypeAt::value -1 >::Result).name() << endl; - cout << Length::value << "\t"; - cout << typeid(TypeAt::value -1>::Result).name() << endl; - cout << Length::value << "\t"; - cout << typeid(TypeAt::value -1>::Result).name() << endl; - } - /* - void Erase() - { - cout <::value << "\t" - << typeid(TypeAt::value -1 >::Result).name() << endl; - cout << Length::value << "\t" - << typeid(TypeAt::value -1>::Result).name() << endl; - cout << Length::value << "\t" - << typeid(TypeAt::value -1>::Result).name() << endl; - } - */ \ No newline at end of file diff --git a/tools/RegressionTest/LokiTest_TypeManip.h b/tools/RegressionTest/LokiTest_TypeManip.h deleted file mode 100644 index 1d864e0..0000000 --- a/tools/RegressionTest/LokiTest_TypeManip.h +++ /dev/null @@ -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 -#define LOKI_TEST_NULLTYPE\ - {\ - Loki::NullType nullTest;\ - cout<<"Testing NullType"<::Result TrueType;\ - typedef Loki::Select::Result FalseType;\ - cout<<"True case: "< tySame;\ - typedef Loki::Conversion tyNoCon;\ - typedef Loki::Conversion tyCon;\ - typedef Loki::Conversion ty2Way;\ - typedef Loki::Conversion tyVoid;\ - cout<< tySame::sameType<<" ::sameType" <::exists" <::exists2Way" <::sameType" <::exists" <::exists2Way" <::sameType" <::exists" <::exists2Way" <::sameType" <::exists" <::exists2Way" <::sameType" <::exists" <::exists2Way" < tyZero;\ - typedef Loki::Int2Type<1> tyOne;\ - typedef Loki::Int2Type<-1> tyNegOne;\ - cout<<" Zero: "<\ - T* Create(const U& arg, Loki::Type2Type)\ - {\ - return new T(arg);\ - }\ - template\ - Widget* Create(const U& arg, Loki::Type2Type)\ - {\ - return new Widget(arg, -1);\ - } -#define LOKI_TEST_TYPE2TYPE\ - {\ - cout<<"Testing Type2Type"<() );\ - delete pNewWidget;\ - Widget* pWidget = Create(100, Loki::Type2Type() );\ - delete pWidget;\ - cout<<"Used Type2Type"<\ - Widget* Create(const U& arg, Loki::Type2Type)\ - {\ - return new Widget(arg, -1);\ - } -#define LOKI_TEST_TYPE2TYPE_BROKEN_PATTERN_MATCHING\ - {\ - cout<<"Testing Type2Type"<() );\ - delete pWidget;\ - cout<<"Used Type2Type"<::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< +#include +#include +#include +#include + +using namespace ::Loki; + +// +// Simulating function templates partial ordering (14.5.5.2): +// The following simple example demonstrate the whole idea +// template void f(T); +// template 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 void f(T, A); +// template void f(T*, B); +// template 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 +struct Order : Order {}; + +template<> +struct Order<0> {}; + +template +struct TypeTag +{ + typedef char (&X)[I]; +}; + +// +// This template class simulate the detection of the best specialization +// +template +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 + static TypeTag<1>::X Match(Type2Type, Type2Type, Order<1>); + + // Match Append + template + static TypeTag<2>::X Match(Type2Type, Type2Type, Order<0>); + + // Match Append> + template + static TypeTag<3>::X Match(Type2Type, Type2Type >, Order<1>); + + // Match Append, T> + template + static TypeTag<4>::X Match(Type2Type >, Type2Type, Order<0>); + + static Type2Type Get1(); + static Type2Type Get2(); + + // VC will fail if the sizeof is written directly to the TypeTag + enum { value = sizeof(Match( Get1(), Get2(), Order<1>() )) }; + +public: + typedef TypeTag Result; +}; + +template 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 struct AppendHelper; + +template<> +struct AppendHelper< TypeTag<1> > +{ // Append + template + struct In + { + typedef NullType Result; + }; +}; + +template<> +struct AppendHelper< TypeTag<2> > +{ // Append + template + struct In + { + typedef TYPELIST_1(T) Result; + }; +}; + +template<> +struct AppendHelper< TypeTag<3> > +{ // Append > + template + struct In + { + typedef typename TList::Head Head; + typedef typename TList::Tail Tail; + + typedef Typelist Result; + //typedef TList Result; + }; +}; + +template<> +struct AppendHelper< TypeTag<4> > +{ // Append, T> + template + struct In + { + typedef typename TList::Head Head; + typedef typename TList::Tail Tail; + + typedef Typelist::Result> Result; + }; +}; + + +template +class Append2 +{ + // First we detect the best specialization + typedef typename AppendPattern::Result Pattern; + +public: + + // Insatiate the best specialization + typedef typename AppendHelper:: + template In::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 +struct PrintTypelist +{ + PrintTypelist() + { + typedef typename TList::Head Head; + typedef typename TList::Tail Tail; + + printf("%s ,", typeid(Head).name()); + + PrintTypelist(); + } +}; + +template<> +struct PrintTypelist +{ + PrintTypelist() + { + printf("\n"); + } +}; + +template +void Test_Append2() +{ + typedef typename TL::Append::Result typelist1_t; + typedef typename Append2::Result typelist2_t; + + // Assert (compile time) that typelist1_t and typelist2_t are the same type + STATIC_CHECK((Conversion::sameType), Append2_Failed); + + PrintTypelist(); + PrintTypelist(); +} + +void Test_Append() +{ + typedef TL::MakeTypeList::Result typelist1_t; + typedef TL::MakeTypeList::Result typelist2_t; + + Test_Append2(); + Test_Append2(); + Test_Append2(); + Test_Append2(); + Test_Append2(); + Test_Append2(); +} + +} // anonymous namespace + + +int main() +{ + Test_Append(); + system("pause"); +} + diff --git a/tools/RegressionTest/Test_AbstractFactory.cpp b/tools/RegressionTest/Test_AbstractFactory.cpp new file mode 100644 index 0000000..e22d8d3 --- /dev/null +++ b/tools/RegressionTest/Test_AbstractFactory.cpp @@ -0,0 +1,148 @@ +#include +#include +#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 apSoldier(abstEnemyFactory.Create()); + + std::cout << apSoldier->SoldierName() << std::endl; + + + auto_ptr apMonster(abstEnemyFactory.Create()); + + std::cout << apMonster->MonsterName() << std::endl; + + + auto_ptr apSuperMonster(abstEnemyFactory.Create()); + + 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); +} + diff --git a/tools/RegressionTest/Test_Factory.cpp b/tools/RegressionTest/Test_Factory.cpp new file mode 100644 index 0000000..2f8d6a4 --- /dev/null +++ b/tools/RegressionTest/Test_Factory.cpp @@ -0,0 +1,35 @@ +#include +#include +#include "Factory.h" +#include "AbstractFactory.h" + +template +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::Result typelist1_t; + +struct Abst : AbstractFactory {}; + +int main() +{ + Factory a; + CloneFactory b; + + typedef AbstractFactory abst_t; + + struct AA1 : ConcreteFactory {}; + AA1 a1; + + struct AA2 : ConcreteFactory {}; + + AA2 a2; +} + diff --git a/tools/RegressionTest/Test_Functor.cpp b/tools/RegressionTest/Test_Functor.cpp new file mode 100644 index 0000000..19eb660 --- /dev/null +++ b/tools/RegressionTest/Test_Functor.cpp @@ -0,0 +1,44 @@ +#include +#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 +} + + diff --git a/tools/RegressionTest/Test_HierarchyGenerators1.cpp b/tools/RegressionTest/Test_HierarchyGenerators1.cpp new file mode 100644 index 0000000..1ebb676 --- /dev/null +++ b/tools/RegressionTest/Test_HierarchyGenerators1.cpp @@ -0,0 +1,69 @@ +#include +#include +#include "HierarchyGenerators.h" + +using namespace ::Loki; + +// +// Helper class for simulating (ranking) partial ordering +// +template +struct Order : Order {}; + +template<> +struct Order<0> {}; + +template class Unit> +class PrintGenScatterHierarchy +{ + template + PrintGenScatterHierarchy(GenScatterHierarchy, Unit> *a, Order<1>) + { + printf("%s\n", typeid(*a).name()); + + GenScatterHierarchy *left = a; + PrintGenScatterHierarchy X1(left); + + GenScatterHierarchy *right = a; + PrintGenScatterHierarchy X2(right); + } + + template + PrintGenScatterHierarchy(GenScatterHierarchy *a, Order<0>) + { + printf("%s\n", typeid(*a).name()); + + Unit *left = a; + (void)left; + + printf("%s\n", typeid(*left).name()); + } + + PrintGenScatterHierarchy(GenScatterHierarchy *a, Order<1>) + { + (void)a; + printf("%s\n", typeid(*a).name()); + } + +public: + template + explicit PrintGenScatterHierarchy(GenScatterHierarchy *a) + { + PrintGenScatterHierarchy(a, Order<1>()); + } +}; + +template class TestUnit {}; +template 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 TestGenScatterHierarchy; + + PrintGenScatterHierarchy X(&TestGenScatterHierarchy); +} + + diff --git a/tools/RegressionTest/Test_HierarchyGenerators2.cpp b/tools/RegressionTest/Test_HierarchyGenerators2.cpp new file mode 100644 index 0000000..1e99212 --- /dev/null +++ b/tools/RegressionTest/Test_HierarchyGenerators2.cpp @@ -0,0 +1,70 @@ +#include +#include +#include "HierarchyGenerators.h" + +using namespace ::Loki; + +// +// Helper class for simulating (ranking) partial ordering +// +template +struct Order : Order {}; + +template<> +struct Order<0> {}; + +template class Unit, class Root> +class PrintGenLinearHierarchy +{ + template + PrintGenLinearHierarchy(GenLinearHierarchy, Unit, Root> *a, Order<1>) + { + printf("%s\n", typeid(*a).name()); + + Unit *base1 = a; + + printf("%s\n", typeid(*base1).name()); + + Root *base2 = base1; (void)base2; + + printf("%s\n", typeid(*base2).name()); + } + + template + PrintGenLinearHierarchy(GenLinearHierarchy, Unit, Root> *a, Order<0>) + { + printf("%s\n", typeid(*a).name()); + + Unit > *base1 = a; + printf("%s\n", typeid(*base1).name()); + + GenLinearHierarchy *base2 = base1; + PrintGenLinearHierarchy X(base2); + } + +public: + template + explicit PrintGenLinearHierarchy(GenLinearHierarchy, Unit, Root> *a) + { + PrintGenLinearHierarchy(a, Order<1>()); + } +}; + +template +class TestUnit : public Base {}; + +class TestRoot {}; + +template 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 TestGenLinearHierarchy; + + PrintGenLinearHierarchy X(&TestGenLinearHierarchy); +} + + diff --git a/tools/RegressionTest/Test_HierarchyGenerators3.cpp b/tools/RegressionTest/Test_HierarchyGenerators3.cpp new file mode 100644 index 0000000..5990ab7 --- /dev/null +++ b/tools/RegressionTest/Test_HierarchyGenerators3.cpp @@ -0,0 +1,76 @@ +#include +#include +#include "HierarchyGenerators.h" + +using namespace ::Loki; + +// +// Helper class for simulating (ranking) partial ordering +// +template +struct Order : Order {}; + +template<> +struct Order<0> {}; + +template 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 + static void Print(GenScatterHierarchy, Unit> &a, Order<1>) + { + printf("%s\n", typeid(a).name()); + + GenScatterHierarchy &left = a; + Print(left); + + GenScatterHierarchy &right = a; + Print(right); + } + + template + static void Print(GenScatterHierarchy &a, Order<0>) + { + printf("%s\n", typeid(a).name()); + + Unit &left = a; + (void)left; + + printf("%s\n", typeid(left).name()); + } + + static void Print(GenScatterHierarchy &a, Order<1>) + { + (void)a; + printf("%s\n", typeid(a).name()); + } + +public: + template + static void Print(GenScatterHierarchy &a) + { + Print(a, Order<1>()); + } + +}; + +template class TestUnit {}; +template struct A {}; +template 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 TestGenScatterHierarchy; + + PrintGenScatterHierarchy::Print(TestGenScatterHierarchy); +} + + diff --git a/tools/RegressionTest/Test_HierarchyGenerators4.cpp b/tools/RegressionTest/Test_HierarchyGenerators4.cpp new file mode 100644 index 0000000..93e4c45 --- /dev/null +++ b/tools/RegressionTest/Test_HierarchyGenerators4.cpp @@ -0,0 +1,72 @@ +#include +#include +#include "HierarchyGenerators.h" + +using namespace ::Loki; + +// +// Helper class for simulating (ranking) partial ordering +// +template +struct Order : Order {}; + +template<> +struct Order<0> {}; + +template class Unit, class Root> +class PrintGenLinearHierarchy +{ + template + static void Print(GenLinearHierarchy, Unit, Root> &a, Order<0>) + { + printf("%s\n", typeid(a).name()); + + Unit > &base1 = a; + printf("%s\n", typeid(base1).name()); + + GenLinearHierarchy &base2 = base1; + Print(base2); + } + + template + static void Print(GenLinearHierarchy, Unit, Root> &a, Order<1>) + { + printf("%s\n", typeid(a).name()); + + Unit &base1 = a; + + printf("%s\n", typeid(base1).name()); + + Root &base2 = base1; (void)base2; + + printf("%s\n", typeid(base2).name()); + } + +public: + template + static void Print(GenLinearHierarchy, Unit, Root> &a) + { + Print(a, Order<1>()); + } +}; + +template +class TestUnit : public Base {}; + +class TestRoot {}; + +template struct A {}; +template 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 TestGenLinearHierarchy; + + PrintGenLinearHierarchy::Print(TestGenLinearHierarchy); +} + + diff --git a/tools/RegressionTest/Test_MultiMethods.cpp b/tools/RegressionTest/Test_MultiMethods.cpp new file mode 100644 index 0000000..5bc0aea --- /dev/null +++ b/tools/RegressionTest/Test_MultiMethods.cpp @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#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 +void Test_HachingDispatcher(TestedHachingExecutor Exec) +{ + using ::std::auto_ptr; + + auto_ptr shape1(new Rectangle); + auto_ptr shape2(new Ellipse); + auto_ptr shape3(new Poly); + auto_ptr 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 ShapeBasicDispatcher; +typedef ::Loki::FnDispatcher ShapeFnDispatcher; +typedef ::Loki::FunctorDispatcher ShapeFunctorDispatcher; + +namespace // anonymous +{ + template + void HatchShapesDo(Shape1 &, Shape2 &) + { + cout << "HatchShapes: " + << typeid(Shape1).name() << ", " + << typeid(Shape2).name() << '\n'; + } + + template + void HatchShapes(Shape &lhs, Shape &rhs) + { + assert(dynamic_cast(&lhs) != 0); + assert(dynamic_cast(&rhs) != 0); + + HatchShapesDo(static_cast(lhs), + static_cast(rhs)); + } + + template + struct HatchShapesFunctor + { + void operator()(Shape1 &lhs, Shape2 &rhs) + { + HatchShapesDo(lhs, rhs); + } + }; + +} // anonymous namespace + +template +void ShapeDispatcherAdd(ShapeBasicDispatcher &x) +{ + x.Add(HatchShapes); +} + +template +void ShapeDispatcherAdd(ShapeFnDispatcher &x) +{ + x.Add(HatchShapes); +} + +template +void ShapeDispatcherAdd(ShapeFunctorDispatcher &x) +{ + x.Add(HatchShapesFunctor()); +} + +template +void Test_LogDispacher() +{ + Dispacher testedBasicDispatcher; + + ShapeDispatcherAdd(testedBasicDispatcher); + ShapeDispatcherAdd(testedBasicDispatcher); + ShapeDispatcherAdd(testedBasicDispatcher); + ShapeDispatcherAdd(testedBasicDispatcher); + ShapeDispatcherAdd(testedBasicDispatcher); + + + using ::std::auto_ptr; + + auto_ptr shape1(new Rectangle); + auto_ptr shape2(new Ellipse); + auto_ptr 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(SymExec); + + HachingExecutor Exec; + Test_HachingDispatcher(Exec); + + Test_LogDispacher(); + Test_LogDispacher(); + Test_LogDispacher(); +} + diff --git a/tools/RegressionTest/Test_Singleton.cpp b/tools/RegressionTest/Test_Singleton.cpp new file mode 100644 index 0000000..ed00eb4 --- /dev/null +++ b/tools/RegressionTest/Test_Singleton.cpp @@ -0,0 +1,34 @@ +#include + +#include +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 SingletonHolder1_t; + typedef SingletonHolder SingletonHolder2_t; + typedef SingletonHolder SingletonHolder3_t; + + A& p = SingletonHolder1_t::Instance(); + SingletonHolder2_t::Instance(); + SingletonHolder3_t::Instance(); + cout << endl << endl; +} + diff --git a/tools/RegressionTest/Test_SmallObj.cpp b/tools/RegressionTest/Test_SmallObj.cpp new file mode 100644 index 0000000..9a3ff61 --- /dev/null +++ b/tools/RegressionTest/Test_SmallObj.cpp @@ -0,0 +1,22 @@ +// +//Test the Small Object Allocator +// MKH +// + +#include + +namespace +{ + struct Test : Loki::SmallObj + { + }; + void Test_SmallObject() + { + Test; + } +}//ns anon + +extern void Test_SmallObj() +{ + Test_SmallObject(); +} \ No newline at end of file diff --git a/tools/RegressionTest/Test_SmartPtr.cpp b/tools/RegressionTest/Test_SmartPtr.cpp new file mode 100644 index 0000000..1866cd7 --- /dev/null +++ b/tools/RegressionTest/Test_SmartPtr.cpp @@ -0,0 +1,286 @@ +#include +#include +#include +#include + +#include +using std::cout; +using std::endl; + +#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; + +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 + struct PrintA + { + void operator()(const SmartPtr_A &spA) const + { + std::cout << spA->name() << ", "; + } + }; + + void Test_SmartPointer() + { + 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; + } + } + +}// anonymous namespace + +extern void Test_SmartPtr() +{ + cout << "Testing Loki\\SmartPtr" << endl; + Test_SmartPointer(); + Test_SmartPtrRL(); + Test_SmartPtrMT(); + Test_RejectNull(); + A::AssertInstCount(); + cout << endl << endl; +} + diff --git a/tools/RegressionTest/Test_SmartPtrWin.cpp b/tools/RegressionTest/Test_SmartPtrWin.cpp new file mode 100644 index 0000000..d1c50e5 --- /dev/null +++ b/tools/RegressionTest/Test_SmartPtrWin.cpp @@ -0,0 +1,145 @@ +#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() +{ +#define MyRefCountedMT RefCountedMTAdj::RefCountedMT +//#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; +} + +int main() +{ + Test_SmartPtr(); + A::AssertInstCount(); +} + diff --git a/tools/RegressionTest/Test_Threads.cpp b/tools/RegressionTest/Test_Threads.cpp new file mode 100644 index 0000000..51be711 --- /dev/null +++ b/tools/RegressionTest/Test_Threads.cpp @@ -0,0 +1,21 @@ +// +//Test the Thread components +// MKH + +#include +using namespace ::Loki; + +#include +using std::cout; +using std::endl; + +namespace +{ +} + +extern void Test_Threads() +{ + cout << "Testing Loki\\Threads" << endl; + SingleThreaded(); + cout << endl << endl; +} \ No newline at end of file diff --git a/tools/RegressionTest/Test_Tuple.cpp b/tools/RegressionTest/Test_Tuple.cpp new file mode 100644 index 0000000..9b25eac --- /dev/null +++ b/tools/RegressionTest/Test_Tuple.cpp @@ -0,0 +1,70 @@ +#include +#include +#include "HierarchyGenerators.h" + +using namespace Loki; + +template +void PrintType(T &) +{ + printf("%s\n", typeid(T).name()); +} + +template +class PrintTuple +{ +public: + + template + explicit PrintTuple(const T &x) + { + PrintTuple X(x); + PrintType(Field(x)); + } +}; + +template<> +class PrintTuple<0> +{ +public: + + template + explicit PrintTuple(const T &x) + { + PrintType(Field<0>(x)); + } +}; + + +template +void PrintTupleFunc() +{ + T x; + + PrintTuple::value - 1> X(x); +} + +template 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 tuple_t; + + PrintTupleFunc(); + + 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; +} + + diff --git a/tools/RegressionTest/Test_TypeList.cpp b/tools/RegressionTest/Test_TypeList.cpp new file mode 100644 index 0000000..e738618 --- /dev/null +++ b/tools/RegressionTest/Test_TypeList.cpp @@ -0,0 +1,223 @@ +#include +#include +#include +#include +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 + struct PrintTypelist + { + PrintTypelist() + { + typedef typename TList::Head Head; + typedef typename TList::Tail Tail; + + printf("%s ,", typeid(Head).name()); + + PrintTypelist(); + } + }; + + template<> + struct PrintTypelist + { + PrintTypelist() + { + printf("\n"); + } + }; + + + void Test_Length() + { + typedef TL::MakeTypeList::Result typelist_t; + + printf("%u\n", TL::Length::value); + } + + + void Test_TypeAt() + { + typedef TL::MakeTypeList::Result typelist_t; + + printf("%s, ", typeid(TL::TypeAt::Result).name()); + printf("%s, ", typeid(TL::TypeAt::Result).name()); + printf("%s, ", typeid(TL::TypeAt::Result).name()); + printf("%s, ", typeid(TL::TypeAt::Result).name()); + printf("%s, ", typeid(TL::TypeAt::Result).name()); + + printf("\n"); + } + + void Test_IndexOf() + { + typedef TL::MakeTypeList::Result typelist_t; + + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + printf("%u, ", TL::IndexOf::value); + + printf("\n"); + } + + void Test_TypeAtNonStrict() + { + typedef TL::MakeTypeList::Result typelist_t; + + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + printf("%s, ", typeid(TL::TypeAtNonStrict::Result).name()); + + printf("\n"); + } + + void Test_Append() + { + typedef TL::MakeTypeList::Result typelist1_t; + typedef TL::MakeTypeList::Result typelist2_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_Erase() + { + typedef TL::MakeTypeList::Result typelist_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_EraseAll() + { + typedef TL::MakeTypeList::Result typelist_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_NoDuplicates() + { + typedef TL::MakeTypeList::Result typelist1_t; + typedef TL::MakeTypeList::Result typelist2_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_Replace() + { + typedef TL::MakeTypeList::Result typelist1_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_ReplaceAll() + { + typedef TL::MakeTypeList::Result typelist1_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_Reverse() + { + typedef TL::MakeTypeList::Result typelist1_t; + + PrintTypelist::Result>(); + } + + void Test_MostDerived() + { + typedef TL::MakeTypeList::Result typelist1_t; + + printf("%s, ", typeid(TL::MostDerived::Result).name()); + printf("%s, ", typeid(TL::MostDerived::Result).name()); + printf("%s, ", typeid(TL::MostDerived::Result).name()); + + printf("\n"); + } + + void Test_DerivedToFront() + { + typedef TL::MakeTypeList::Result typelist1_t; + typedef TL::MakeTypeList::Result typelist2_t; + + PrintTypelist::Result>(); + PrintTypelist::Result>(); + } + + void Test_DerivedToFrontAll() + { + typedef TL::MakeTypeList::Result typelist1_t; + typedef TL::MakeTypeList::Result typelist2_t; + + PrintTypelist::Result>(); + PrintTypelist::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; +} + + diff --git a/tools/RegressionTest/Test_Variant.cpp b/tools/RegressionTest/Test_Variant.cpp new file mode 100644 index 0000000..e0025a0 --- /dev/null +++ b/tools/RegressionTest/Test_Variant.cpp @@ -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 '' to '', possible loss of data + +#include +#include +#include +#include "Variant.h" + +using namespace std; + +int main() +{ + try + { + typedef Variant 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(); + assert(p != 0); + *p += '!'; + assert(fld1.Get() == "Hello, world!"); + + fld3 = fld1; + assert(fld1.Get() == "Hello, world!"); + assert(fld3.Get() == "Hello, world!"); + + fld3 = std::string("Assignment"); + assert(fld3.Get() == "Assignment"); + + DBField fld5; + + assert(fld5.TypeId() == typeid(string)); + assert(fld5.GetPtr()->empty()); + + DBField fld4 = fld1; + assert(fld4.TypeId() == typeid(string)); + assert(fld4.Get() == "Hello, world!"); + + DBField fld(45); + float f = fld.ConvertTo(); + assert(f == 45); + (void)f; + + fld2.ChangeType(); + assert(fld2.Get() == 25); + + typedef Variant AlternateDBField; + AlternateDBField fld6(fld1); + assert(fld6.Get() == "Hello, world!"); + + fld6 = fld3; + assert(fld6.Get() == "Assignment"); + +#if defined(_MSC_VER) && _MSC_VER >= 1300 + // + // Variant with VC non-standard alignment support + // + typedef TYPELIST_3(string, double, int) DBField2Typelist; + typedef Variant > AlternateDBField2; + + AlternateDBField2 fld7(fld6); + assert(fld7.Get() == "Assignment"); + + fld7 = fld2; + assert(fld7.Get() == 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."; + } +} + diff --git a/tools/RegressionTest/Test_Visitor.cpp b/tools/RegressionTest/Test_Visitor.cpp new file mode 100644 index 0000000..f277b0b --- /dev/null +++ b/tools/RegressionTest/Test_Visitor.cpp @@ -0,0 +1,158 @@ +#include +#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 + , public BaseVisitorImpl +{ +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(); +} +