no message
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@107 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
4bfc42e511
commit
80e63b12a3
1 changed files with 319 additions and 215 deletions
|
@ -1,6 +1,6 @@
|
|||
Loki VC 6.0 Port or how to produce C1001 - Internal Compiler Errors
|
||||
-------------------------------------------------------------------
|
||||
Version: 0.3b
|
||||
Version: 0.5
|
||||
|
||||
Introduction/Compatibility:
|
||||
---------------------------
|
||||
|
@ -30,6 +30,25 @@ If you use Singletons with longevity you must add Singleton.cpp to your project/
|
|||
Fixes:
|
||||
------
|
||||
|
||||
Feb 2003:
|
||||
---------
|
||||
* created new versions of Functor.h, Visitor.h and MultiMethods.h that
|
||||
now can handle void return types transparently.
|
||||
|
||||
* ported SmartPtr's Ownership-Policy RefCountedMT
|
||||
|
||||
* Added isFunctionPointer to TypeTraits.
|
||||
|
||||
* Replaced all pointer-type dummy-parameters needed as a workaround
|
||||
for VC's 'explicit template argument specification'-bug with Typ2Type-dummy
|
||||
parameters.
|
||||
|
||||
* fixed the problems with BindFirst (Functor.h) that led to
|
||||
C1001-Internal compiler errors.
|
||||
|
||||
* fixed numerous other bugs.
|
||||
|
||||
|
||||
Jan 30, 2003:
|
||||
-------------
|
||||
* In TypeTraits.h: Fixed bugs in TypeTraits' scalar and array detection.
|
||||
|
@ -77,30 +96,29 @@ A. partial template specialization.
|
|||
B. template template parameters.
|
||||
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.
|
||||
E. Template parameters with default type void
|
||||
F. return statements with an expression of type cv void in functions with a return type of cv void.
|
||||
|
||||
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 led
|
||||
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.
|
||||
The problem with this approach is MSVC's 'dependent template typedef bug'. MSVC 6.0 does not
|
||||
allow something like this:
|
||||
The problem with this approach is MSVC's 'dependent template typedef bug'.
|
||||
MSVC 6.0 does not allow something like this:
|
||||
|
||||
[code]
|
||||
template <class APolicy, class T>
|
||||
struct Foo
|
||||
{
|
||||
// 'error C1001 - Internal Compiler Error' here
|
||||
// error C2903: 'In' : symbol is neither a class template nor a function template
|
||||
typedef typename APolicy::template In<T> type;
|
||||
};
|
||||
|
||||
[/code]
|
||||
|
||||
To make a long story short, I finally decided to use boost::mpl's apply-technique to
|
||||
|
@ -124,7 +142,7 @@ Unfortunately the MSVC 6.0 supports neither of them.
|
|||
struct Foo
|
||||
{
|
||||
template <class T>
|
||||
T Func(T* pDummy1);
|
||||
T Func(Type2Type<T>);
|
||||
};
|
||||
[/code]
|
||||
in this port.
|
||||
|
@ -151,7 +169,7 @@ Unfortunately the MSVC 6.0 supports neither of them.
|
|||
}
|
||||
[/code]
|
||||
|
||||
As a workaround i added dummy-parameters.
|
||||
As a workaround i added dummy-parameters (of type Int2Type).
|
||||
|
||||
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
|
||||
|
@ -160,12 +178,49 @@ Unfortunately the MSVC 6.0 supports neither of them.
|
|||
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 (an udt). This change is
|
||||
transparent to 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 :-(
|
||||
F. To workaround void returns I did the following:
|
||||
From every original class I moved those functions that potentially
|
||||
produce void returns to new classes. One for the general case and
|
||||
one for the void case.
|
||||
In the class for the general case I implemented the functions in the original way.
|
||||
In the class for the void case I removed the return statements and therefore the
|
||||
potential void return.
|
||||
Depending on the return type, the original class inherits from the
|
||||
corresponding new class and thus gets the proper implementation of
|
||||
the previously removed functions.
|
||||
|
||||
For example:
|
||||
[code]
|
||||
template <class R> struct Foo
|
||||
{
|
||||
R Func() { return R(); }
|
||||
};
|
||||
[/code]
|
||||
becomes:
|
||||
[code]
|
||||
namespace Private
|
||||
{
|
||||
template <class R> struct FooBase
|
||||
{
|
||||
R Func() {return R();}
|
||||
};
|
||||
struct FooVoidBase
|
||||
{
|
||||
typedef void R;
|
||||
R Func() {}
|
||||
};
|
||||
}
|
||||
template <class R>
|
||||
struct Foo : public Select<IsVoid<R>::value, FooVoidBase, FooBase<R> >::Result
|
||||
{};
|
||||
[/code]
|
||||
Please note that *all* new base classes are only meant as a hidden
|
||||
implementation detail.
|
||||
You should never use any of them directly or indirectly. In particular don't
|
||||
make use of the possible derived-to-base conversion.
|
||||
|
||||
In the old version of Functor.h I changed a ResultType of type void to
|
||||
VoidAsType (an udt). This change is transparent to the user of Functor.
|
||||
|
||||
Some words to template-ctors resp. template assignment operators:
|
||||
The MSVC 6.0 introduces an order-dependency for template ctor
|
||||
|
@ -261,7 +316,7 @@ Interface changes:
|
|||
assert(TypeTraits<const volatile void>::isConst == 1)
|
||||
assert(TypeTraits<const volatile void>::isVolatile == 1)
|
||||
|
||||
* This port adds isEnum and isMemberFuncPointer
|
||||
* This port adds isEnum, isMemberFunctionPointer and isFunctionPointer.
|
||||
|
||||
|
||||
5. HierarchyGenerator.h
|
||||
|
@ -338,7 +393,7 @@ Interface changes:
|
|||
Calling syntax changed from:
|
||||
ConcProduct* p = aFactory.Create<ConcProduct>();
|
||||
to
|
||||
ConcProduct* p = aFactory.Create((ConcProduct*)0);
|
||||
ConcProduct* p = aFactory.Create(Type2Type<ConcProduct>());
|
||||
|
||||
|
||||
8. SmartPtr.h
|
||||
|
@ -357,6 +412,14 @@ Interface changes:
|
|||
a set of complete new classes (and macros) for void. Default arguments of type void
|
||||
were replaced by arguments of type int.
|
||||
|
||||
Update:
|
||||
-------
|
||||
In the new version of Visitor.h there are no longer extra classes for void.
|
||||
Instead the original classes are now able to handle the return type void.
|
||||
However there are still two sets of macros. One for return type = void
|
||||
(DEFINE_VISITABLE_VOID, DEFINE_CYCLIC_VISITABLE_VOID) and one for return
|
||||
type != void (DEFINE_VISITABLE, DEFINE_CYCLIC_VISITABLE)
|
||||
|
||||
|
||||
10. MultiMethods.h
|
||||
|
||||
|
@ -368,6 +431,47 @@ Interface changes:
|
|||
* dummy parameters were added to functions that otherwise would depend on
|
||||
explicit template argument specification (14.8.1).
|
||||
|
||||
Update:
|
||||
-------
|
||||
* The port now supports functions with return type void.
|
||||
|
||||
Some words to BasicDispatcher:
|
||||
------------------------------
|
||||
You can't use a (namespace level) template function as callback-function
|
||||
for BasicDispatcher. This is because using the VC 6.0 you can't explicity
|
||||
specify the template-paramters when adding the concrete function instance
|
||||
to the dispatcher.
|
||||
Normaly you can write something like this:
|
||||
[code]
|
||||
template <class DerivedShape1, class DerivedShape2>
|
||||
int HatchShapes(Shape&, Shape&) {...}
|
||||
|
||||
typedef ::Loki::BasicDispatcher<Shape> Dispatcher;
|
||||
|
||||
void Func(Dispatcher& x)
|
||||
{
|
||||
x.Add(&HatchShapes<Circle, Rectangle>);
|
||||
}
|
||||
[/code]
|
||||
Using the VC 6.0 this is not possible, because there is no
|
||||
way to specify the types for DerivedShape1 and DerivedShape2 (at least
|
||||
I know of no way).
|
||||
|
||||
As a workaround use a helper-template class in conjunction with
|
||||
a static member function:
|
||||
[code]
|
||||
template <class DerivedShape1, class DerivedShape2>
|
||||
struct Hatch_Helper
|
||||
{
|
||||
int HatchShapes(Shape&, Shape&) {...}
|
||||
};
|
||||
|
||||
typedef ::Loki::BasicDispatcher<Shape> Dispatcher;
|
||||
|
||||
void Func(Dispatcher& x)
|
||||
{
|
||||
x.Add(&Hatch_Helper<Circle, Rectangle>::HatchShapes);
|
||||
}
|
||||
|
||||
More info:
|
||||
----------
|
||||
|
|
Loading…
Reference in a new issue