public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/21665] New: template template parameter function overload not recognized
@ 2005-05-19 14:21 johill at lanl dot gov
  2005-05-19 14:39 ` [Bug c++/21665] " johill at lanl dot gov
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: johill at lanl dot gov @ 2005-05-19 14:21 UTC (permalink / raw)
  To: gcc-bugs

The following does not compile with g++ 3.4.2 on Solaris and 3.2.3 on Linux, but
probably should, and does with other compilers.

class PropertyId;
class ArraySegment;
class StringSegment;
class EnumStateSet;
class PropertyCatalog;
class PropertyCatalog;
class Time;

class PropertyId {
};

extern class PropertyCatalog & voidContainer;

template < template < class T > class PROPERTY >
class PropertyManipulator {
public:
    virtual void reveal ( PROPERTY < float > & )  = 0;
    virtual void reveal ( PROPERTY < double > & )  = 0;
    virtual void reveal ( PROPERTY < char > & ) = 0; 
    virtual void reveal ( PROPERTY < signed char > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned char > & ) = 0; 
    virtual void reveal ( PROPERTY < short > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned short > & ) = 0; 
    virtual void reveal ( PROPERTY < int > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned int > & ) = 0; 
    virtual void reveal ( PROPERTY < long > & ) = 0; 
    virtual void reveal ( PROPERTY < unsigned long > & ) = 0; 
    virtual void reveal ( PROPERTY < Time > & ) = 0; 
    virtual void reveal ( PROPERTY < StringSegment > & ) = 0; 
    virtual void reveal ( PROPERTY < EnumStateSet > & ) = 0; 
    virtual void reveal ( PROPERTY < ArraySegment > & ) = 0; 
    virtual void reveal ( PROPERTY < PropertyCatalog > & ) = 0; 
};

template < class CATALOG > 
class PropertyBase {
public:
    PropertyBase ( 
        const PropertyId & id, CATALOG & subordinate );
    const PropertyId & id () const;
    CATALOG & subordinate () const;
private:
    const PropertyId & _id;
    CATALOG & _subordinateProperties;
};

template < class T > 
class PropertyType : public PropertyBase < const PropertyCatalog > {
public:
    PropertyType ( const PropertyId & id,  
        const PropertyCatalog & = voidContainer );
    template < class C >
    PropertyType ( 
        const PropertyId & id, const C * pC, T ( C :: * p ), 
        const PropertyCatalog & subordinate = voidContainer );
};

template < class T > 
class PropertyMutable : public PropertyBase < PropertyCatalog > {
public:
    PropertyMutable ( 
        const PropertyId & id, T & value,  
        PropertyCatalog & subordinate = voidContainer );
    template < class C >
    PropertyMutable ( 
        const PropertyId & id, C * pC, T ( C :: * p ), 
        PropertyCatalog & subordinate = voidContainer );
    T & value ();
private:
    T & _scalar;
};

template < class T > 
class PropertyImmutable : public PropertyBase < const PropertyCatalog > {
public:
    PropertyImmutable ( 
        const PropertyId & id, const T & value,  
        const PropertyCatalog & subordinate = voidContainer );
    template < class C >
    PropertyImmutable ( 
        const PropertyId & id, const C * pC, T ( C :: * p ), 
        const PropertyCatalog & subordinate = voidContainer );
    const T & value () const;
private:
    const T & _scalar;
};

class PropertySkeleton {
public:
    virtual void traverse ( 
        PropertyManipulator < PropertyType > & ) = 0;
};

class PropertyCatalog {
public:
    virtual void traverse ( 
        PropertyManipulator < PropertyMutable > & ) = 0;
    virtual void traverse ( 
        PropertyManipulator < PropertyImmutable > & ) const = 0;
    // false returned when the property does not exist, otherwise true
    virtual bool find ( 
        const PropertyId & id, PropertyManipulator < PropertyImmutable > & )
const = 0;
};

// ----------------- begin property implementation
----------------------------------

class VoidContainer : public PropertyCatalog {
    void traverse ( 
        PropertyManipulator < PropertyMutable > & ) {}
    void traverse ( 
        PropertyManipulator < PropertyImmutable > & ) const {}
    // false returned when the property does not exist, otherwise true
    bool find ( 
        const PropertyId & id, PropertyManipulator < PropertyImmutable > & ) const 
    {
        return false;
    }
};

VoidContainer aVoidContainer;

class PropertyCatalog & voidContainer = aVoidContainer;

template < class CATALOG > 
inline PropertyBase < CATALOG > :: PropertyBase ( 
    const PropertyId & id, CATALOG & subordinate ) :
        _id ( id ), _subordinateProperties ( subordinate )
{
}

template < class CATALOG > 
inline const PropertyId & PropertyBase < CATALOG > :: id () const
{
    return _id;
}

template < class CATALOG > 
inline CATALOG & PropertyBase < CATALOG > :: subordinate () const
{
    return _subordinateProperties;
}

template < class T > 
inline PropertyType < T > :: PropertyType ( 
        const PropertyId & id, 
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate )
{
}
        
template < class T > template < class C >
inline PropertyType < T > :: PropertyType ( 
    const PropertyId & id, const C *, T ( C :: * ), 
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate )
{
}

template < class T > 
inline PropertyMutable < T > :: PropertyMutable ( 
        const PropertyId & id, T & value, PropertyCatalog & subordinate ) :
    PropertyBase < PropertyCatalog > ( id, subordinate ), _scalar ( value )
{
}

template < class T > template < class C >
inline PropertyMutable < T > :: PropertyMutable ( 
    const PropertyId & id, C * pC, T ( C :: * p ), 
        PropertyCatalog & subordinate ) :
    PropertyBase < PropertyCatalog > ( id, subordinate ), _scalar ( pC->*p )
{
}

template < class T > 
inline T & PropertyMutable < T > :: value () 
{
    return _scalar;
}

template < class T > 
inline PropertyImmutable < T > :: PropertyImmutable ( 
        const PropertyId & id, const T & value,  
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate ), _scalar ( value )
{
}

template < class T > template < class C >
inline PropertyImmutable < T > :: PropertyImmutable ( 
    const PropertyId & id, const C * pC, T ( C :: * p ), 
        const PropertyCatalog & subordinate ) :
    PropertyBase < const PropertyCatalog > ( id, subordinate ), _scalar ( pC->*p )
{
}

template < class T > 
inline const T & PropertyImmutable < T > :: value () const
{
    return _scalar;
}

// --------------------------- begin application specific -------------

PropertyId propertyX;
PropertyId propertyY;

class MyContainerSkeleton : public PropertySkeleton {
public:
    void traverse ( 
        PropertyManipulator < PropertyType > & );
};

class MyContainer : 
    public PropertyCatalog, public MyContainerSkeleton {
public:
    void traverse ( 
        PropertyManipulator < PropertyMutable > & );
    void traverse ( 
        PropertyManipulator < PropertyImmutable > & ) const;
    static void traverseTypes ( 
        PropertyManipulator < PropertyType > & );
    bool find ( 
        const PropertyId & id, PropertyManipulator < PropertyImmutable > & ) const;
private:
    int x;
    float y;
    template < class C, template < class T > class PROPERTY >
    static void traverseTempl ( 
        C * pContainer, PropertyManipulator < PROPERTY > & ); 
};

// C is a template purely so that we can reveal const and non-const 
// using the same template, but perhaps there is another way
template < class C, template < class T > class PROPERTY >
void MyContainer::traverseTempl ( 
    C * pContainer, PropertyManipulator < PROPERTY > & manipulator )
{
    manipulator.reveal ( 
	    PROPERTY < int > ( propertyX, pContainer, & MyContainer::x ) );
    manipulator.reveal ( 
	    PROPERTY < float > ( propertyY, pContainer, & MyContainer::y ) );
}

void MyContainer::traverse ( 
    PropertyManipulator < PropertyMutable > & manipulator ) 
{
    MyContainer::traverseTempl ( this, manipulator );
}

void MyContainer::traverse ( 
    PropertyManipulator < PropertyImmutable > & manipulator ) const 
{
    MyContainer::traverseTempl ( this, manipulator );
}

void MyContainerSkeleton::traverse ( 
    PropertyManipulator < PropertyType > & manipulator )
{
    MyContainer::traverseTypes ( manipulator );
}

void MyContainer::traverseTypes ( 
    PropertyManipulator < PropertyType > & manipulator )
{
    const MyContainer * pC = 0;
    MyContainer::traverseTempl ( pC, manipulator );
}

MyContainer mc;

-- 
           Summary: template template parameter function overload not
                    recognized
           Product: gcc
           Version: 3.4.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: johill at lanl dot gov
                CC: gcc-bugs at gcc dot gnu dot org
  GCC host triplet: solaris/sparc also earlier version on Linux
GCC target triplet: solaris/sparc also earlier version on Linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21665


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-05-19 16:12 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-19 14:21 [Bug c++/21665] New: template template parameter function overload not recognized johill at lanl dot gov
2005-05-19 14:39 ` [Bug c++/21665] " johill at lanl dot gov
2005-05-19 14:40 ` johill at lanl dot gov
2005-05-19 14:51 ` pinskia at gcc dot gnu dot org
2005-05-19 16:10 ` johill at lanl dot gov
2005-05-19 16:12 ` johill at lanl dot gov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).