diff --git a/MSVC/1200/HierarchyGenerators.h b/MSVC/1200/HierarchyGenerators.h index bbc4e81..27fff37 100644 --- a/MSVC/1200/HierarchyGenerators.h +++ b/MSVC/1200/HierarchyGenerators.h @@ -13,7 +13,8 @@ // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// -// Last update: Oct 24, 2002 +// Last update: Dec 08, 2002 + #ifndef HIERARCHYGENERATORS_INC_ #define HIERARCHYGENERATORS_INC_ @@ -68,15 +69,40 @@ namespace Loki // // See "Metaprogramming VC++ - more of Loki ported" from Mat Marcus // (http://lists.boost.org/MailArchives/boost/msg20915.php) - +// +// Update: +// ------- +// The first version of GenScatterHierarchy did not work with typelists +// containing equal types. The MSVC 6.0 erroneously complains about +// inaccessible base-classes (error C2584). +// This new version adds Dummy-classes to the left branch of the generated +// hierarchy to workaround this VC-Bug. +// It creates hierarchies like this: +// +// Holder NullType +// \ / +//Holder GenScatter GenScatter +// \ \ / +//VC_InaccessibleBase InheritFromTo +// \ | +//GenScatter GenScatter +// \ / +// InheritFromTo +// | +// | +//GenScatter +// +// Of course this version of GenScatterHierarchy generates a lot more +// classes (5*n) than Alexandrescu's original implementation (3*n) +// + template class GenScatterHierarchy; - namespace Private { + template - class InheritFromTwo : public T, public U - { - public: + struct InheritFromTwo : public T, public U + { }; template @@ -90,16 +116,34 @@ namespace Private struct In : public GenScatterHierarchy { typedef - InheritFromTwo < GenScatterHierarchy, + InheritFromTwo < VC_InaccessibleBase, typename T::Tail>, GenScatterHierarchy > type; - typedef GenScatterHierarchy LeftBase; + typedef VC_InaccessibleBase,typename T::Tail> LeftBase; typedef GenScatterHierarchy RightBase; }; }; - + + // Specialization for a typelist with only one element + template <> + struct GenScatterImpl + { + template + struct In : public GenScatterHierarchy + { + // for the last Holder-class no dummy class is needed. + typedef + InheritFromTwo < GenScatterHierarchy, + GenScatterHierarchy + > type; + typedef GenScatterHierarchy LeftBase; + typedef GenScatterHierarchy RightBase; + }; + }; // Specialization for a single type template <> struct GenScatterImpl @@ -111,7 +155,9 @@ namespace Private ApplyInnerType::type type; typedef type LeftBase; typedef EmptyType RightBase; + //typedef AtomicType::THIS_SELECTED bla; }; + }; // Specialization for NullType @@ -127,14 +173,11 @@ namespace Private }; }; } // end namespace Private - + template class GenScatterHierarchy : public Private::GenScatterImpl < - IS_TYPELIST(T)::type_id == TL::Private::Typelist_ID ? TL::Private::Typelist_ID : - IS_TYPELIST(T)::type_id == TL::Private::AtomList_ID ? TL::Private::Typelist_ID : - IS_TYPELIST(T)::type_id == TL::Private::NullType_ID ? TL::Private::NullType_ID : - TL::Private::NoneList_ID + IS_TYPELIST(T)::type_id >::template In::type { public: @@ -142,28 +185,22 @@ namespace Private < TL::Private::IsTypelist::value, T, void >::Result TList; - typedef typename Private::GenScatterImpl - < - IS_TYPELIST(T)::type_id == TL::Private::Typelist_ID ? TL::Private::Typelist_ID : - IS_TYPELIST(T)::type_id == TL::Private::AtomList_ID ? TL::Private::Typelist_ID : - IS_TYPELIST(T)::type_id == TL::Private::NullType_ID ? TL::Private::NullType_ID : - TL::Private::NoneList_ID - >::template In::LeftBase LeftBase; - - typedef typename Private::GenScatterImpl - < - IS_TYPELIST(T)::type_id == TL::Private::Typelist_ID ? TL::Private::Typelist_ID : - IS_TYPELIST(T)::type_id == TL::Private::AtomList_ID ? TL::Private::Typelist_ID : - IS_TYPELIST(T)::type_id == TL::Private::NullType_ID ? TL::Private::NullType_ID : - TL::Private::NoneList_ID - >::template In::RightBase RightBase; - + + typedef typename Private::GenScatterImpl + < + IS_TYPELIST(T)::type_id + >::template In::LeftBase LeftBase; + typedef typename Private::GenScatterImpl + < + IS_TYPELIST(T)::type_id + >::template In::RightBase RightBase; + template struct Rebind { typedef ApplyInnerType::type Result; }; }; - + //////////////////////////////////////////////////////////////////////////////// // function template Field // Accesses a field in an object of a type generated with GenScatterHierarchy @@ -269,11 +306,12 @@ namespace Private // If Do is not a template and H& is used as parameter // MSVC will give a linker error. template - static ResultType& Do(T& obj) + static ResultType& Do(H& obj, T*) { - typedef typename T::RightBase RightBase; + //typedef typename T::RightBase RightBase; + //RightBase& rightBase = obj; RightBase& rightBase = obj; - return FieldHelper::template In::Do(rightBase); + return FieldHelper::template In::Do(rightBase, (int*)0); } }; }; @@ -317,7 +355,7 @@ namespace Private public: template - static ResultType& Do(T& obj) + static ResultType& Do(H& obj, T*) { LeftBase& leftBase = obj; return leftBase; @@ -334,17 +372,14 @@ namespace Private // returns a reference to Unit, where Unit is the template used to generate H // and T is the i-th type in the typelist //////////////////////////////////////////////////////////////////////////////// - template typename FieldHelper::template In,UnitWrapper>::ResultType& - Field(GenScatterHierarchy& obj) + Field(GenScatterHierarchy& obj, Int2Type) { - typedef typename GenScatterHierarchy H; - - return FieldHelper::template In::Do(obj); + typedef typename GenScatterHierarchy H; + return FieldHelper::template In::Do(obj, (int*)0); } - //////////////////////////////////////////////////////////////////////////////// // class template GenLinearHierarchy // Generates a linear hierarchy starting from a typelist and a template @@ -386,7 +421,8 @@ namespace Private typedef typename TList::Tail Tail; public: - typedef ApplyInnerType2 >::type Result; + typedef typename + ApplyInnerType2 >::type Result; }; }; @@ -400,7 +436,7 @@ namespace Private typedef typename TList::Head Head; public: - typedef ApplyInnerType2::type Result; + typedef typename ApplyInnerType2::type Result; }; }; @@ -417,13 +453,12 @@ namespace Private > ::template In::Result TempType; - typedef typename - Private::VC_Base_Workaround type; + typedef Private::VC_Base_Workaround type; // this is nothing more than a typedef to the created hierarchy (TempType). // But if we try to inherit directly from TempType VC 6.0 // will produce a "Error C2516. : is not a legal base class." - typedef type::LeftBase Base; + typedef typename type::LeftBase Base; }; } // namespace Private @@ -450,11 +485,26 @@ namespace Private } // namespace Loki +#if defined (_MSC_VER) && _MSC_VER <= 1300 +#define FIELD(Obj, Nr) \ + Field(Obj, Int2Type()) +#else +#define FIELD(Obj, Nr) \ + Field(Obj) +#endif + //////////////////////////////////////////////////////////////////////////////// // Change log: // June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!! // September 16, 2002: Fixed dependent template, using "::template" syntax. T.S. // Oct 24, 2002: ported by Benjamin Kaufmann to MSVC 6 +// Dec 08, 2002: Fixed problems with MSVC6-Version of GenScatterHierarchy when +// used with typelists containing equal types. B.K. +// New Version is ugly :-( +// Dec 08, 2002: Interface changed for Field-Function. The old version does not +// work correctly due to the "Explicitly Specified Template +// Functions Not Overloaded Correctly"-Bug +// (Microsoft KB Article - 240871). B.K. //////////////////////////////////////////////////////////////////////////////// #undef IS_TYPELIST #endif // HIERARCHYGENERATORS_INC_ diff --git a/MSVC/1200/MSVC6Helpers.h b/MSVC/1200/MSVC6Helpers.h index dab78f3..0fe0230 100644 --- a/MSVC/1200/MSVC6Helpers.h +++ b/MSVC/1200/MSVC6Helpers.h @@ -1,3 +1,7 @@ +// Last update: Dec 03, 2002 +// Added qualification ::Loki::Private:: to types from the Private-Namespace +// Thanks to Adi Shavit + #ifndef MSVC6HELPERS__H #define MSVC6HELPERS__H #if !defined (_MSC_VER) || _MSC_VER >= 1300 @@ -7,18 +11,22 @@ namespace Loki { namespace Private { + template + struct VC_InaccessibleBase : public T + {}; + // workaround for the "Error C2516. : is not a legal base class" - // Use VC_Base_Workaround's LeftBase instead of the + // Use VC_Base_Workaround's LeftBase instead of the // alleged illegal base class. template struct VC_Base_Workaround : public T, public U { typedef T LeftBase; }; - + // MSVC 6.0 does not allow the return of - // expressions of type "cv void" in a functions with a return - // type of cv void (6.6.3). + // expressions of type "cv void" in a functions with a return + // type of cv void (6.6.3). // Functor.h uses this Type as a workaround. struct VoidAsType {}; @@ -50,10 +58,10 @@ namespace Loki { template struct In; }; template< typename T1 > struct Result : public - VC_WORKAROUND< AlwaysFalse::value >::template In + VC_WORKAROUND< ::Loki::Private::AlwaysFalse::value >::template In { - typedef VC_WORKAROUND< AlwaysFalse::value >::template In Base; - + typedef VC_WORKAROUND< ::Loki::Private::AlwaysFalse::value >::template In Base; + }; }; //////////////////////////////////////////////////////////////////////////////// @@ -72,7 +80,7 @@ namespace Loki {template struct In; }; template< typename T1, typename T2 > struct Result : public - VC_WORKAROUND< AlwaysFalse::value >::template In + VC_WORKAROUND< ::Loki::Private::AlwaysFalse::value >::template In { }; }; @@ -88,9 +96,9 @@ namespace Loki // i first saw this technique in boost's mpl library. //////////////////////////////////////////////////////////////////////////////// template - struct Apply1 : Private::ApplyImpl1::template Result + struct Apply1 : ::Loki::Private::ApplyImpl1::template Result { - typedef typename Private::ApplyImpl1::template Result::Base Base; + typedef typename ::Loki::Private::ApplyImpl1::template Result::Base Base; }; //////////////////////////////////////////////////////////////////////////////// // class template Apply2 @@ -100,9 +108,9 @@ namespace Loki // i first saw this technique in boost's mpl library. //////////////////////////////////////////////////////////////////////////////// template - struct Apply2 : Private::ApplyImpl2::template Result + struct Apply2 : ::Loki::Private::ApplyImpl2::template Result { - + }; //////////////////////////////////////////////////////////////////////////////// @@ -117,11 +125,11 @@ namespace Loki struct ApplyInnerType { template struct Wrapper_VC : Wrapper {}; - + template<> struct Wrapper_VC { template struct In; }; - typedef typename - Wrapper_VC::value>::template In::type type; + typedef typename + Wrapper_VC< ::Loki::Private::AlwaysFalse::value>::template In::type type; }; //////////////////////////////////////////////////////////////////////////////// // class template ApplyInnerType2 @@ -135,23 +143,24 @@ namespace Loki struct ApplyInnerType2 { template struct Wrapper_VC : Wrapper {}; - + template<> struct Wrapper_VC { template struct In; }; - typedef typename - Wrapper_VC::value>::template In::type type; + typedef typename + Wrapper_VC< ::Loki::Private::AlwaysFalse::value>::template In::type type; }; template struct ApplyInnerType4 { template struct Wrapper_VC : Wrapper {}; - + template<> struct Wrapper_VC { template struct In; }; - typedef typename - Wrapper_VC::value>::template In::type type; + typedef typename + Wrapper_VC< ::Loki::Private::AlwaysFalse::value>::template In::type type; }; + } #endif \ No newline at end of file diff --git a/MSVC/1200/Readme.txt b/MSVC/1200/Readme.txt index 7d436ee..492f35b 100644 --- a/MSVC/1200/Readme.txt +++ b/MSVC/1200/Readme.txt @@ -1,11 +1,12 @@ Loki VC 6.0 Port or how to produce C1001 - Internal Compiler Errors ------------------------------------------------------------------- +Version: 0.3 Introduction/Compatibility: --------------------------- This is a partial MSVC 6.0 Sp5 compatible port of Andrei Alexandrescu's excellent Loki Library. -Because I could not retain the originial interface in all places, this port is not -compatible to the original library and therefore code using this port *cannot* generally be +Because I could not retain the originial interface in all places, this port is not +compatible to the original library and therefore code using this port *cannot* generally be used together with the original lib. This is, of course, a great pity. So if you know of a complete and full interface-compatible VC 6.0 @@ -13,19 +14,45 @@ port or if you know how to improve this port, please let me know. Contact: -------- -For any suggestions, bug reports, comments and questions please email me to +For any suggestions, bug reports, comments and questions please email me to Hume@c-plusplus.de Using this port: ---------------- -To use this port, simply extract the files from the archive, give your compiler access to +To use this port, simply extract the files from the archive, give your compiler access to their path, and include them appropriately in your code via #include. -If you use the small object allocator directly or indirectly (through the Functor class) +If you use the small object allocator directly or indirectly (through the Functor class) you must add SmallObj.cpp to your project/makefile. If you use Singletons with longevity you must add Singleton.cpp to your project/makefile. +Fixes: +------ + + Dec 08, 2002: + ------------- + * In HierarchyGenerators.h: Sergey Khachatrian reported a bug + in GenScatterHierarchy when used with a typelist containing + equal types (e.g. GenScatterHierarchy + resp. Tuple) + Fixing the bug I found another MSVC6-Problem in the Field-function. + The workaround for this problems results in an interface change. + + please refer to the section "Interface changes" below for further information. + + Dec 03, 2002 + ------------- + * In MSVC6Helpers.h: The original version failed to qualify some types from the + Private-Namespace. + Thanks to Adi Shavit for pointing that out + + * In Threads.h: Changed wrong ctor/dtor names in ObjectLevelLockable. + Thanks to Adi Shavit for pointing that out + + Nov 19, 2002: + ------------- + * In SmartPtr.h: Changed template ctors. See Notes. Notes: ------ @@ -37,18 +64,17 @@ C. explicit template argument specification for member- and nonmeber functions. D. covariant return types. E. Template parameters with a default type void F. return statements with an expression of type cv in functions with a return type of cv void. -G. Template-ctor resp. template assignment operator Unfortunately the MSVC 6.0 supports neither of them. A. I used various techniques to simulate partial template specialization. In some cases these techniques allowed me to retain the original interfaces but often that was not - possible (or better: i did not find a proper solution). In any case it leads + possible (or better: i did not find a proper solution). In any case it leads to increasing code complexity :-) B. One way to simulate template template parameters is to replace the template class with a normal class containing a nested template class. You then move the original functionality - to the nested class. + to the nested class. The problem with this approach is MSVC's 'dependent template typedef bug'. MSVC 6.0 does not allow something like this: @@ -58,17 +84,17 @@ Unfortunately the MSVC 6.0 supports neither of them. { // 'error C1001 - Internal Compiler Error' here typedef typename APolicy::template In type; - }; + }; [/code] - To make a long story short, I finally decided to use boost::mpl's apply-technique to + To make a long story short, I finally decided to use boost::mpl's apply-technique to simulate template template parameters. This approach works fine with MSVC 6.0. But be warned, this technique uses not valid C++. - Of course, replacing template template parameters always results in some interface changes. + Of course, replacing template template parameters always results in some interface changes. - C. I added dummy-Parameters to (Member-)Functions that depend on explicit template - argument specification. These dummy-Parameters help the compiler in deducing the template + C. I added dummy-Parameters to (Member-)Functions that depend on explicit template + argument specification. These dummy-Parameters help the compiler in deducing the template parameters that otherwise need to be explicitly specified. Example: [code] @@ -88,103 +114,187 @@ Unfortunately the MSVC 6.0 supports neither of them. [/code] in this port. + Update: + ------- + The MSVC 6.0 sometimes does not overload normal functions depending + on explicit argument specification correctly (see: Microsoft KB Article - 240871) + The following code demonstrates the problem: + [code] + template + void BugDemonstration(T p) + { + printf("BugDemonstration called with i = %d\n", i); + } + + int main() + { + GenScatterHierarchy Bla; + // will always print: "BugDemonstration called with i = 2"; + BugDemonstration<0>(Bla); + BugDemonstration<1>(Bla); + BugDemonstration<2>(Bla); + } + [/code] + + As a workaround i added dummy-parameters. D. Virtual functions that use covariant return types (e.g. return a pointer to Derived) in the original library were changed so that they have exactly the same return type as the original virtual function (e.g. return a pointer to Base). - + E. All template parameters that have a default type of void in the original lib now have int as default type. - F. In Functor.h I changed a ResultType of type void to VoidAsType (a udt). This change is transparent - for the user of Functor. + F. In Functor.h I changed a ResultType of type void to VoidAsType (an udt). This change is transparent + for the user of Functor. Because I could not think of any general and transparent workaround I followed different strategies. In Visitor.h for example I created new classes (and macros) for the void-case. In other places (for example: MultiMethod.h) this port simply fails to support void as return type :-( - G. The MSVC 6.0 does not recognize a copy-ctor resp. a copy-assignment if a templated version - is present. On the other hand the MSVC 6.0 allows explicit template specialization in class - scope. I used this "feature" as a workaround for code like this: - [code] - template - struct Foo - { - Foo(const Foo&); - template - Foo(const Foo&); - }; - [/code] - - Under MSVC 6.0 the above code becomes: - [code] - template - struct Foo - { - template - Foo(const Foo&); +Some words to template-ctors resp. template assignment operators: +The MSVC 6.0 introduces an order-dependency for template ctor +resp. template assignemt operators. +If you need both a copy-ctor and a template copy ctor (same for copy-assignment), then +you *must* write the templated version first. +So instead of +[code] +template +struct Foo +{ + Foo(const Foo&) + {} + template + Foo(const Foo& r) + {} +}; +[/code] +you *need* to write: +[code] +template +struct Foo +{ + template + Foo(const Foo& r) + {} - // copy-ctor for Foos with equal T - // not valid c++ - template <> - Foo(const Foo&); - }; - [/code] + Foo(const Foo& r) + {} +}; +[/code] +Many thanks to Nelson Elói for pointing that out and for providing me +with this solution. + +The above solution unfortunately does not work if the template ctor does not have +the form of a copy-ctor. If you write something like this (as in the functor-class): +[code] +template +struct Foo +{ + template + Foo(Fun r) + {} + + Foo(const Foo& r) + {} +}; +[/code] +then the VC will no longer find a copy-ctor. + +Because of this, i can't use Nelson Elói's solution in Functor.h Interface changes: ------------------ 1. In Threads.h: - - * Thread-Policies changed from class templates to normal classes containing a - nested class template 'In'. + + * Thread-Policies changed from class templates to normal classes containing a + nested class template 'In'. consequences: This change is not very dramatic because it won't break code using this port when switching to the original library (only new Thread-Policies must be changed) 2. In Singleton.h: - - * The Creation- and Lifetime-Policies are no longer class templates. Instead they all use - Member-Templates. + + * The Creation- and Lifetime-Policies are no longer class templates. Instead they all use + Member-Templates. consequences: Again this change will only break new Policies when switching to the original library. 3. In Functor.h: - + * No covariant return types. - + consequences: - DoClone always returns a FunctorImplBase* where R is the functor's return + DoClone always returns a FunctorImplBase* where R is the functor's return type and ThreadingModel its current ThreadingModel. - -4. TypeTraits.h + +4. TypeTraits.h * Because VC 6.0 lacks partial template specialization, the TypeTraits-Class provides not all the stuff provided by the original library's version. - + 5. HierarchyGenerator.h - + * I used Mat Marcus' approach to port GenScatterHierarchy. See http://lists.boost.org/MailArchives/boost/msg20915.php) for the consequences. * Same for GenLinearHierarchy * Unit is no longer a template template parameter. - + consequences: For every concrete unit-template there must be a normal class containing a nested-template class called 'In'. 'In' should only contain a typedef to the concrete Unit. + Update: + The port's original version of GenScatterHierarchy does not work when used + with typelists containing equal types. + The problem is due to a VC bug. The VC fails to compile code similar + to this, although it is perfectly legal. + [code] + template + class Wrapper + {}; + + template + struct B : public Wrapper + {}; + + // ERROR: 'A' : direct base 'Wrapper' is inaccessible; already a base of 'B' + template + class A : public B, public Wrapper + {}; + [/code] + + Unfortunately my workaround has a big drawback. + GenScatterHierarchy now has to generate a lot more classes. + Alexandrescu's original implementation generates 3*n classes (n - number of types in the typelist) + The old version of my port creates 4 * n + 1 + The new version will create 5 * n + + The fix also reveals the "Explicitly Specified Template Functions Not Overloaded Correctly"-Bug + (Microsoft KB Article - 240871) in the Field-Function taking a nontype int Parameter. + + This leads to an interface change: + Instead of: Field<0>(obj) + one now has to write + Field(obj, Int2Type<0>()); + + I added a macro FIELD. Using this macro one can write + FIELD(obj, 0) + + 6. Factory.h - + * The Error-Policy for Factory and CloneFactory is no longer a template template parameter. - Use a class with member-templates instead. - + Use a class with member-templates instead. + consequences: This change will only break new Policies when switching to the original library. @@ -192,7 +302,7 @@ Interface changes: 7. AbstractFactory.h * no covariant return types - + * no template template parameters For every concrete Factory-Unit there must be a normal class containing a nested-template class called 'In'. 'In' shall contain a typedef to the @@ -203,7 +313,7 @@ Interface changes: ConcProduct* p = aFactory.Create(); to ConcProduct* p = aFactory.Create((ConcProduct*)0); - + 8. SmartPtr.h @@ -214,7 +324,7 @@ Interface changes: 9. Visitor.h - * no template template parameters + * no template template parameters (see 7.for a description of the consequences) * This port fails to correctly support void return types. As a workaround it provides @@ -229,7 +339,7 @@ Interface changes: * This port does not support functions with return type void. - * dummy parameters were added to functions that otherwise would depend on + * dummy parameters were added to functions that otherwise would depend on explicit template argument specification (14.8.1). diff --git a/MSVC/1200/SmartPtr.h b/MSVC/1200/SmartPtr.h index de1c575..bfeffe0 100644 --- a/MSVC/1200/SmartPtr.h +++ b/MSVC/1200/SmartPtr.h @@ -13,21 +13,18 @@ // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// -// Last update: Oct 26, 2002 +// Last update: Nov 19, 2002 + // replaced all template template parameters with 'normal' parameters // For each Policy there is now a wrapper-class (non template class) // containing a nested template class called In which // provides a typedef (type) to the real Policy-class // -// VC special: The MSVC 6.0 has problems with template ctors resp. template -// assignemt operators. If there exists a template copy ctor (a template op=) the -// compiler will complain about a non-template version. On the other hand, -// if one does not provide a non-template version and one tries to -// initialize a new object with one having the same type the compiler will synthesize -// a default version (the same for assignment). -// Because the MSVC allows explicit specialization in class scope i used -// this as a workaround. -// Instead of: +// VC special: The MSVC 6.0 introduces an order-dependency for template ctor +// resp. template assignemt operators. +// If you need both a copy-ctor and a template copy ctor (same for copy-assignment), then +// you *must* write the templated version first. +// So instead of // template // struct Foo // { @@ -37,19 +34,21 @@ // Foo(const Foo& r) // {} // }; -// -// this port uses: -// +// you *need* to write: // template // struct Foo // { // template // Foo(const Foo& r) // {} -// template <> +// // Foo(const Foo& r) // {} // }; +// +// Many thanks to Nelson Elói for pointing that out and for providing me +// with this solution + #ifndef SMARTPTR_INC_ #define SMARTPTR_INC_ @@ -93,19 +92,16 @@ namespace Loki // The storage policy doesn't initialize the stored pointer // which will be initialized by the OwnershipPolicy's Clone fn -#if !defined(_MSC_VER) + + // do not alter the order of the following two constructors + // otherwise the MSVC 6.0 will not compile the class. + template + DefaultSPStorage(const DefaultSPStorage&) {} + DefaultSPStorage(const DefaultSPStorage&) {} -#endif - template - DefaultSPStorage(const DefaultSPStorage&) - {} -#if _MSC_VER <= 1200 - template <> - DefaultSPStorage(const DefaultSPStorage&) - {} -#endif - DefaultSPStorage(const StoredType& p) : pointee_(p) {} + + DefaultSPStorage(const StoredType& p) : pointee_(p) {} PointerType operator->() const { return pointee_; } @@ -166,24 +162,19 @@ namespace Loki *pCount_ = 1; } -#if !defined(_MSC_VER) - RefCounted(const RefCounted& rhs) - : pCount_(rhs.pCount_) - {} -#endif - - // MWCW lacks template friends, hence the following kludge + // do not alter the order of the following two constructors + // otherwise the MSVC 6.0 will fail to compile the class. + + // MWCW lacks template friends, hence the following kludge template RefCounted(const RefCounted& rhs) : pCount_(reinterpret_cast(rhs).pCount_) {} - -#if _MSC_VER <= 1200 - template<> + RefCounted(const RefCounted& rhs) : pCount_(rhs.pCount_) {} -#endif + P Clone(const P& val) { ++*pCount_; @@ -976,11 +967,9 @@ namespace Private } } - -#if !defined(_MSC_VER) - SmartPtr(CopyArg& rhs) - : SP(rhs), OP(rhs), KP(rhs), CP(rhs) -#endif + + // do not alter the order of the following three constructors + // otherwise the MSVC 6.0 will fail to compile the class. template < typename T1, @@ -1005,29 +994,16 @@ namespace Private : SP(rhs), OP(rhs), KP(rhs), CP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } -#if _MSC_VER <= 1200 - - template <> SmartPtr(CopyArg& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) -#endif - { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } - SmartPtr(ByRef rhs) - : SP(rhs), OP(rhs), KP(rhs), CP(rhs) - {} - operator ByRef() { return ByRef(*this); } -#if !defined(_MSC_VER) - SmartPtr& operator=(CopyArg& rhs) - { - SmartPtr temp(rhs); - temp.Swap(*this); - return *this; - } -#endif - template + + + // do not alter the order of the following three copy-assignment operators + // otherwise the MSVC 6.0 will fail to compile the class. + template < typename T1, class OP1, @@ -1057,15 +1033,13 @@ namespace Private temp.Swap(*this); return *this; } -#if _MSC_VER <= 1200 - template<> + SmartPtr& operator=(CopyArg& rhs) { SmartPtr temp(rhs); temp.Swap(*this); return *this; } -#endif void Swap(SmartPtr& rhs) { OP::Swap(rhs); diff --git a/MSVC/1200/Threads.h b/MSVC/1200/Threads.h index a59d64f..14d6511 100644 --- a/MSVC/1200/Threads.h +++ b/MSVC/1200/Threads.h @@ -8,10 +8,13 @@ // affects only default template arguments //////////////////////////////////////////////////////////////////////////////// -// Last update: Oct 07, 2002 +// Last update: Dec 03, 2002 // note: In this VC 6 port all template policies become non-templates with // either member-template functions or a nested template struct named In +// Changed wrong ctor/dtor names in ObjectLevelLockable. +// Thanks to Adi Shavit for pointing that out + #ifndef DEFAULT_THREADING #define DEFAULT_THREADING /**/ ::Loki::SingleThreaded #endif @@ -90,12 +93,12 @@ namespace Loki CRITICAL_SECTION mtx_; public: - ObjectLevelLockable() + In() { ::InitializeCriticalSection(&mtx_); } - ~ObjectLevelLockable() + ~In() { ::DeleteCriticalSection(&mtx_); } diff --git a/MSVC/1200/TypeManip.h b/MSVC/1200/TypeManip.h index 6728af4..6ac973e 100644 --- a/MSVC/1200/TypeManip.h +++ b/MSVC/1200/TypeManip.h @@ -37,7 +37,8 @@ namespace Loki template struct Int2Type { - enum { value = v }; + Int2Type() {} + enum { value = v }; }; //////////////////////////////////////////////////////////////////////////////// diff --git a/MSVC/1200/TypeTraits.h b/MSVC/1200/TypeTraits.h index 1c6a74d..3f87133 100644 --- a/MSVC/1200/TypeTraits.h +++ b/MSVC/1200/TypeTraits.h @@ -173,7 +173,7 @@ namespace Loki class TypeTraits { private: -// static T MakeT(...); + static T MakeT(...); template struct Wrap{}; struct pointer_helper { @@ -232,8 +232,8 @@ namespace Loki enum {isReference = sizeof( is_reference_helper2( is_reference_helper1(Wrap()))) == sizeof(Private::YES)}; -// enum {isPointer = sizeof(is_pointer(MakeT())) == sizeof(Private::YES)}; -// enum {isMemberPointer = sizeof(is_pointer2member(MakeT())) == sizeof(Private::YES)}; + enum {isPointer = sizeof(is_pointer(MakeT())) == sizeof(Private::YES)}; + enum {isMemberPointer = sizeof(is_pointer2member(MakeT())) == sizeof(Private::YES)}; enum {isArray = sizeof( is_array_helper1( is_array_helper2(Wrap()))) == sizeof(Private::YES)}; @@ -264,7 +264,7 @@ namespace Loki isVolatile = sizeof(is_volatile(Wrap())) == sizeof(Private::YES) }; - enum { isScalar = isStdArith /* || isPointer */ /* || isMemberPointer */ }; + enum { isScalar = isStdArith || isPointer || isMemberPointer}; private: typedef typename Private::AdjReference:: template In::Result AdjType;