Oh, I see it - they are wxStringArray ;-)
But I was able to create an example with only 160 KB of preprocessed code which compiles cleanly with gcc 3.2 and gcc 3.4, but not with gcc 4.1. It is about 60 lines with classes definition and including only sqplus.h
Edit: Now I am on 32KB of preprocessed code and still shortening ;-)
typedef char wxChar;
extern const wxChar* wxEmptyString;
class wxString
{
protected:
wxChar *m_pchData;
void Init() { m_pchData = (wxChar *)wxEmptyString; }
public:
wxString() { Init(); }
wxString(const wxString& stringSrc)
{
m_pchData = stringSrc.m_pchData; // share same data
}
};
class wxArrayString
{
public:
wxArrayString() { }
wxArrayString(const wxArrayString& a) { }
wxArrayString(int sz, const wxChar** a);
wxArrayString(int sz, const wxString* a);
};
class CompileOptionsBase
{
public:
CompileOptionsBase() {}
virtual ~CompileOptionsBase() {}
virtual const wxArrayString& GetLinkerOptions() const;
virtual const wxString& GetVar(const wxString& key) const;
virtual bool GetModified() const;
};
#include <sqplus.h>
DECLARE_INSTANCE_TYPE(wxString);
DECLARE_INSTANCE_TYPE(wxArrayString);
DECLARE_INSTANCE_TYPE(CompileOptionsBase);
namespace ScriptBindings
{
void RegisterBindings()
{
SqPlus::SQClassDef<CompileOptionsBase>("CompileOptionsBase").
func(&CompileOptionsBase::GetLinkerOptions, "GetLinkerOptions").
func(&CompileOptionsBase::GetVar, "GetVar").
func(&CompileOptionsBase::GetModified, "GetModified");
}
} // namespace ScriptBindings
Well, I am there - 90 lines and 1800 bytes. When take away the SqPlus namespace, the code compiles. So it looks like something between the templates and namespaces. When I move the Push(bool) and Push(int) down to the Push(string) or the other way Push(string) up to Push(bool), it compiles too. Really interesting compiler behaiour ;-)
class String
{
public:
String();
};
class Base
{
public:
Base();
const String& GetString(const String& key) const;
bool GetBool() const;
};
namespace SqPlus {
template<class T>
struct TypeWrapper {
};
template<typename T>
T * GetInstance() {
return (T *)0;
}
inline void Push(bool value) { }
inline bool Get(TypeWrapper<bool>) { return *GetInstance<bool>(); }
inline void Push(int value) { }
template<class RT>
struct ReturnSpecialization {
template <typename Callee>
static void Call(Callee & callee,RT (Callee::*func)() const) {
RT ret = (callee.*func)();
Push(ret);
}
template <typename Callee,typename P1>
static void Call(Callee & callee,RT (Callee::*func)(P1) const) {
RT ret = (callee.*func)(Get(TypeWrapper<P1>()));
Push(ret);
}
};
template<typename Callee,typename RT>
void Call(Callee & callee, RT (Callee::*func)() const) {
ReturnSpecialization<RT>::Call(callee,func);
}
template<typename Callee,typename RT,typename P1>
void Call(Callee & callee,RT (Callee::*func)(P1) const) {
ReturnSpecialization<RT>::Call(callee,func);
}
template<typename Callee,typename Func>
inline void RegisterInstance(Callee & callee,Func func) {
Call(*(Callee *)0,*(Func *)0);
}
template<typename TClassType>
struct SQClassDef {
SQClassDef();
template<typename Func>
SQClassDef & func(Func pfunc) {
RegisterInstance(*(TClassType *)0,pfunc);
return *this;
}
};
inline void Push(const String & value) { }
inline const String & Get(TypeWrapper<const String &>) { return *GetInstance<String>(); }
inline void Push(Base * value) { }
inline Base & Get(TypeWrapper<Base &>) { return *GetInstance<Base>(); }
};
void RegisterBindings()
{
SqPlus::SQClassDef<Base>().
func(&Base::GetString).
func(&Base::GetBool);
}