// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef NARROW_IMPL_H
#define NARROW_IMPL_H

//
// Define macro for _narrow_impl declaration
//
// T = The class name
//
#ifdef HAVE_NO_RTTI

#define OB_MAKE_NARROW_IMPL(T) \
static T* _narrow_impl(CORBA_Object_ptr); \
virtual void* _OB_narrowHelp(const char*) const;

#else

#define OB_MAKE_NARROW_IMPL(T) \
static T* _narrow_impl(CORBA_Object_ptr);

#endif

//
// Define macros for _narrow_impl implementation
//
// T            = Fully scoped class name, e.g. "MyClass::SubClass"
// B1, B2, ...  = The super classes
//
#ifdef HAVE_NO_RTTI

#define OB_MAKE_NARROW_MAIN_IMPL(T) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    void* v = 0; \
    if(p) \
        v = p -> _OB_narrowHelp(# T); \
    if(v) \
	return (T*)v; \
    else \
	return 0; \
}

#define OB_MAKE_NARROW_IMPL_0(T) \
OB_MAKE_NARROW_MAIN_IMPL(T) \
void* T::_OB_narrowHelp(const char* name) const \
{ \
    if(strcmp(# T , name) == 0) \
	return (void*)this; \
    else \
	return 0; \
}
	
#define OB_MAKE_NARROW_IMPL_1(T, B1) \
OB_MAKE_NARROW_MAIN_IMPL(T) \
void* T::_OB_narrowHelp(const char* name) const \
{ \
    if(strcmp(# T, name) == 0) \
	return (void*)this; \
    else \
	return B1::_OB_narrowHelp(name); \
}
	
#define OB_MAKE_NARROW_IMPL_2(T, B1, B2) \
OB_MAKE_NARROW_MAIN_IMPL(T) \
void* T::_OB_narrowHelp(const char* name) const \
{ \
    if(strcmp(# T, name) == 0) \
	return (void*)this; \
    else \
    { \
	void* v = B1::_OB_narrowHelp(name); \
        if(!v) \
	    v = B2::_OB_narrowHelp(name); \
        return v; \
    } \
}
	
#define OB_MAKE_NARROW_IMPL_3(T, B1, B2, B3) \
OB_MAKE_NARROW_MAIN_IMPL(T) \
void* T::_OB_narrowHelp(const char* name) const \
{ \
    if(strcmp(# T, name) == 0) \
	return (void*)this; \
    else \
    { \
	void* v = B1::_OB_narrowHelp(name); \
        if(!v) \
	    v = B2::_OB_narrowHelp(name); \
        if(!v) \
	    v = B3::_OB_narrowHelp(name); \
        return v; \
    } \
}

#define OB_MAKE_NARROW_IMPL_4(T, B1, B2, B3, B4) \
OB_MAKE_NARROW_MAIN_IMPL(T) \
void* T::_OB_narrowHelp(const char* name) const \
{ \
    if(strcmp(# T, name) == 0) \
	return (void*)this; \
    else \
    { \
	void* v = B1::_OB_narrowHelp(name); \
        if(!v) \
	    v = B2::_OB_narrowHelp(name); \
        if(!v) \
	    v = B3::_OB_narrowHelp(name); \
        if(!v) \
	    v = B4::_OB_narrowHelp(name); \
        return v; \
    } \
}

#define OB_MAKE_NARROW_IMPL_5(T, B1, B2, B3, B4, B5) \
OB_MAKE_NARROW_MAIN_IMPL(T) \
void* T::_OB_narrowHelp(const char* name) const \
{ \
    if(strcmp(# T, name) == 0) \
	return (void*)this; \
    else \
    { \
	void* v = B1::_OB_narrowHelp(name); \
        if(!v) \
	    v = B2::_OB_narrowHelp(name); \
        if(!v) \
	    v = B3::_OB_narrowHelp(name); \
        if(!v) \
	    v = B4::_OB_narrowHelp(name); \
        if(!v) \
	    v = B5::_OB_narrowHelp(name); \
        return v; \
    } \
}

#else

#define OB_MAKE_NARROW_IMPL_0(T) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    return dynamic_cast<T*>(p); \
}

#define OB_MAKE_NARROW_IMPL_1(T, B1) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    return dynamic_cast<T*>(p); \
}

#define OB_MAKE_NARROW_IMPL_2(T, B1, B2) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    return dynamic_cast<T*>(p); \
}

#define OB_MAKE_NARROW_IMPL_3(T, B1, B2, B3) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    return dynamic_cast<T*>(p); \
}

#define OB_MAKE_NARROW_IMPL_4(T, B1, B2, B3, B4) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    return dynamic_cast<T*>(p); \
}

#define OB_MAKE_NARROW_IMPL_5(T, B1, B2, B3, B4, B5) \
T* T::_narrow_impl(CORBA_Object_ptr p) \
{ \
    return dynamic_cast<T*>(p); \
}

#endif

#endif
