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:
humesikkins 2003-02-27 15:56:49 +00:00
parent 4bfc42e511
commit 80e63b12a3

View file

@ -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:
----------