// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_core/src/acdk/lang/sys/RefHolder.h,v 1.71 2005/04/25 13:19:34 kommer Exp $
#ifndef acdk_lang_sys_RefHolder_h
#define acdk_lang_sys_RefHolder_h
#include <stddef.h>
#include "sys.h"
#include "core_vector.h"
#ifdef ACDK_USE_EXT_REFERER
#include "RefHeap.h"
#endif
/FONT>
/**
use implements to derived from interfaces or
extending an interface
@ingroup acdkkeywords
*/
#define implements virtual public
/**
use extends to derived normal classes
You MUST NOT use implements (virtual) in this case
otherwise Memory-Management will not work
@ingroup acdkkeywords
*/
#define extends public
using namespace ::acdk::lang;
template <class T> class RefHolder;
template <class T> class ObjectArrayImpl;
//template <class T> class RObjectArrayImpl;
#ifdef _MSC_VER
#pragma warning (disable : 4786) // template to long regarding debugging
#endif
/**
Represents a 'null' Reference (equivalent to a null pointer)
@ingroup acdkkeywords
*/
enum NilRef
{
Nil = 0
};
/** this function is only hack to solve forward declaration problems */
namespace acdk {
namespace lang {
class InterfaceBase;
class ObjectBase;
class acdk::lang::Object;
typedef ::RefHolder< ::acdk::lang::Object> acdk::lang::Object;
class String;
ACDK_CORE_PUBLIC String* createNewString(const char* str);
namespace sys {
class Allocator;
}
namespace dmi {
class ClazzInfo;
class ScriptVar;
}
}
}
namespace {
#if !defined(DOXYGENONLY)
/** @internal */
template <class Base, class Candidate>
class DeriveChecker
{
typedef char (&no)[1];
typedef char (&yes)[2];
struct Meth
{
static yes Test(Base*);
static no Test(...);
};
public:
enum {
CandidateIsDerivedFromBase =
(sizeof(Meth::Test((Candidate*)0)) == sizeof(yes))
};
};
#endif //!defined(DOXYGENONLY)
} // anon namespace
#if !defined(DOXYGENONLY)
/** @internal */
template <class Base, class Derived>
inline
bool is_base_of(const Derived& o)
{
return DeriveChecker<Base, Derived>::CandidateIsDerivedFromBase;
}
/** @internal */
template <class ToT, class FromT>
inline
ToT object_cast(const FromT& f)
{
if (is_base_of<ToT>(f))
return static_cast<ToT>(f);
return dynamic_cast<ToT>(f);
}
/** @internal */
template <class ToT, class FromT>
inline
ToT interface_cast(const FromT& f)
{
if (is_base_of<ToT>(f))
return static_cast<ToT>(f);
return dynamic_cast<ToT>(f);
}
/** @internal */
#define REFH_TRYDOWNCAST_OBJ(ret, T, oiptr) \
if (is_base_of<T>(*(oiptr))) \
ret = static_cast<T*>(oiptr); \
else \
ret = dynamic_cast<T*>(oiptr);
#ifndef ACDK_NO_NULLPOINTER_CHECKING
/** @internal */
# define ACDK_ASSERT_NULL_PTR(ptr) \
if (ptr == 0) ::acdk::lang::ObjectBase::_throwNullPointerException();
#else
/FONT>
# define ACDK_ASSERT_NULL_PTR(ptr)
#endif
/FONT>
#endif //!defined(DOXYGENONLY)
/**
Helper method to throw a cast exception
@throw ClassCastException
@param clazz target type
@param iface source type
*/
ACDK_CORE_PUBLIC void badCast(const ::acdk::lang::dmi::ClazzInfo* clazz, ::acdk::lang::ObjectBase* iface);
/**
Helper method to throw a cast exception
@throw ClassCastException
@param clazz target type
@param iface source type
*/
ACDK_CORE_PUBLIC void badBasicArrayCast(const ::acdk::lang::dmi::ClazzInfo* clazz, ::acdk::lang::ObjectBase* iface);
/**
Helper method to throw a cast exception
@throw ClassCastException
@param clazz target type
@param iface source type
*/
ACDK_CORE_PUBLIC void badObjectArrayCast(const ::acdk::lang::dmi::ClazzInfo* clazz, ::acdk::lang::ObjectBase* iface);
#if !defined(DOXYGENONLY)
/** @internal */
inline void* acdk_allocate(size_t size);
/** @internal */
inline void acdk_deallocate(void* ptr);
/** @internal */
inline void* acdk_allocate(size_t size, ::acdk::lang::sys::Allocator* allocator);
/** @internal */
inline void acdk_deallocate(void* ptr, ::acdk::lang::sys::Allocator* allocator);
template <class I> class InterfaceHolder;
//#define USE_REFHOLDER1_H
//#include "RefHolder1.h"
//#include "RefHolder2.h" not working
#include "RefHolder3.h"
//#include "RefHolder4.h"
//#include "RefHolder5.h"
template <class T>
inline
bool operator==(NilRef nil, const RefHolder<T>& o)
{
return o.iptr() == 0;
}
template <class T>
inline
bool operator!=(NilRef nil, const RefHolder<T>& o)
{
return o.iptr() != 0;
}
template <class T>
inline
bool operator==(NilRef nil, const InterfaceHolder<T>& o)
{
return o.iptr() == 0;
}
template <class T>
inline
bool operator!=(NilRef nil, const InterfaceHolder<T>& o)
{
return o.iptr() != 0;
}
template <class T>
inline
bool equalsObjects(const RefHolder<T>& f, const RefHolder<T>& s)
{
if (f == Nil && s == Nil)
return true;
if (f == Nil || s == Nil)
return false;
return s->equals(f);
}
#endif //!defined(DOXYGENONLY)
/**
Macro to declare a ACDK class
It defines following types:
- ClassName
- RClassName
- ClassNameArray
- RClassNameArray
@ingroup acdkmacros
@ingroup acdksmartptr
*/
#define ACDK_DECL_CLASS(ClassName) \
class ClassName; \
typedef ::RefHolder<ClassName> R##ClassName; \
typedef ::ObjectArrayImpl<R##ClassName> ClassName##Array; \
typedef ::RObjectArrayImpl<R##ClassName> R##ClassName##Array
/**
Macro to declare a ACDK interface
It defines following types:
- ClassName
- RClassName
- ClassNameArray
- RClassNameArray
@ingroup acdkmacros
@ingroup acdksmartptr
*/
#define ACDK_DECL_INTERFACE(InterfaceName) \
class InterfaceName; \
typedef ::InterfaceHolder<InterfaceName> R##InterfaceName; \
typedef ::ObjectArrayImpl<R##InterfaceName> InterfaceName##Array; \
typedef ::RObjectArrayImpl<R##InterfaceName> R##InterfaceName##Array
/**
Macro to declare a ACDK exception type
@param ClassName name of the exception type
@param SuperName name of the derived exception type
It defines following types:
- ClassName
- RClassName
- ClassNameArray
- RClassNameArray
@ingroup acdkmacros
@ingroup acdksmartptr
@see ACDK_DECL_THROWABLE_FQ
*/
#define ACDK_DECL_THROWABLE(ClassName, SuperName) \
class ClassName; \
typedef ::ThrowableHolder<ClassName, R##SuperName> R##ClassName; \
typedef ::ObjectArrayImpl<R##ClassName> ClassName##Array; \
typedef ::RObjectArrayImpl<R##ClassName> R##ClassName##Array
/**
Macro to declare a ACDK exception type
@param ClassName name of the exception type
@param sns namespace of the derived exception type
@param SuperName name of the derived exception type
It defines following types:
- ClassName
- RClassName
- ClassNameArray
- RClassNameArray
@ingroup acdkmacros
@ingroup acdksmartptr
*/
#define ACDK_DECL_THROWABLE_FQ(ClassName, sns, SuperName) \
class ClassName; \
typedef ::ThrowableHolder<ClassName, sns R##SuperName> R##ClassName; \
typedef ::ObjectArrayImpl<R##ClassName> ClassName##Array; \
typedef ::RObjectArrayImpl<R##ClassName> R##ClassName##Array
/**
Macro to declare a ACDK class Array.
This is usefull to declare Arrays from Arrays
It defines following types:
- ClassNameArray
- RClassNameArray
@ingroup acdkmacros
@ingroup acdksmartptr
*/
#define ACDK_DECL_CLASS_ARRAY(ClassName) \
typedef ::ObjectArrayImpl<R##ClassName> ClassName##Array; \
typedef ::RObjectArrayImpl<R##ClassName> R##ClassName##Array
/**
alias to ACDK_DECL_CLASS_ARRAY
@ingroup acdkmacros
*/
#define ACDK_DECL_ARRAY(ClassName) ACDK_DECL_CLASS_ARRAY(ClassName)
/**
used to import the given ACDK-Class into current namespace
imports following type names:
- ClassName
- RClassName
- ClassNameArray
- RClassNameArray
@param Namespace the namspace of the class
@param ClassName the class name
@ingroup acdkmacros
@ingroup acdksmartptr
*/
#define USING_CLASS(Namespace, ClassName) \
using Namespace ClassName;\
using Namespace R##ClassName; \
using Namespace ClassName##Array; \
using Namespace R##ClassName##Array
/**
use to define meta info for enumerations which are declared and used inside a executable or static library
@ingroup acdkmacros
*/
#define ACDK_DEF_ENUM(EnumName) \
class EnumName##MetaInf \
{ \
public: \
static ::acdk::lang::dmi::ClazzEnumInfo* GetEnumInfo(); \
}
/**
use to define meta info for enumerations which are declared and used inside shared library
@ingroup acdkmacros
*/
#define ACDK_DEF_LIB_ENUM(export, EnumName) \
class export EnumName##MetaInf \
{ \
public: \
static ::acdk::lang::dmi::ClazzEnumInfo* GetEnumInfo(); \
}
/**
container to collect references of fields
@internal
*/
typedef acdk::lang::sys::core_vector<acdk::lang::Object*> FieldReferences;
#ifndef ACDK_NOMETAINFO
/**
Use this to delcare a class as ACDK-Class with available Metainformatione.
You can use mmmc to generate Metainformation for a given class or package.
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_WITH_METAINFO(ClassName) \
public: \
virtual ::acdk::lang::dmi::ClazzInfo* getClazzInfo() { return clazzInfo(); } \
static ::acdk::lang::dmi::ClazzInfo* clazzInfo(); \
static ::acdk::lang::RClass GetClass(); \
virtual void getCollectableFields(FieldReferences& fields); \
inline static void* _castToInterfacePtr(::acdk::lang::Object* optr) { return reinterpret_cast<void*>(dynamic_cast<ClassName*>(optr)); } \
private: \
friend struct ClassName##_MetainfoWrapper;
/**
This version is similar to ACDK_WITH_METAINFO, but
the methods declarations has to be written into the class.
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_WITH_METAINFO2(ClassName) \
private: \
friend struct ClassName##_MetainfoWrapper;
/**
Produces only information needed
for the Garbage collector, but no further Metainfo
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_WITH_MI_GCINFO \
public: \
virtual void getCollectableFields(FieldReferences& fields); \
private: \
/**
Produces only information about member
no DMI interface or information about functions
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_WITH_MI_MEMBER(ClassName) \
public: \
virtual void getCollectableFields(FieldReferences& fields); \
virtual ::acdk::lang::dmi::ClazzInfo* getClazzInfo() { return clazzInfo(); } \
static ::acdk::lang::dmi::ClazzInfo* clazzInfo(); \
static ::acdk::lang::RClass GetClass(); \
static void* _castToInterfacePtr(::acdk::lang::Object* optr) { return reinterpret_cast<void*>(dynamic_cast<ClassName*>(optr)); } \
private: \
friend struct ClassName##_MetainfoWrapper;
#else //ACDK_NOMETAINFO
#define ACDK_WITH_METAINFO(ClassName)
#define ACDK_WITH_MI_GCINFO
#endif //ACDK_NOMETAINFO
#ifndef ACDK_NOMETAINFO
/**
If you don't want to use Metainformation, you can use this
macro. The purpose is for debugging only, otherwise not recommended!
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define DECL_ACDK_DUMMYMETACLASS \
public: \
virtual ::acdk::lang::dmi::ClazzInfo* getClazzInfo() { return 0; } \
static ::acdk::lang::dmi::ClazzInfo* clazzInfo() { return 0; } \
static ::acdk::lang::RClass GetClass() { return Nil; } \
virtual void getCollectableFields(FieldReferences& fields) { } \
/**
A given ACDK should not implement its own meta info, but just use
the metainfo from a given super class.
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define DECL_ACDK_DEFAULT_METACLASS(Super) \
public: \
virtual ::acdk::lang::dmi::ClazzInfo* getClazzInfo() { return Super::getClazzInfo(); } \
static ::acdk::lang::dmi::ClazzInfo* clazzInfo() { return Super::clazzInfo(); } \
static ::acdk::lang::RClass GetClass() { return Super::GetClass(); } \
virtual void getCollectableFields(FieldReferences& fields) { Super::getCollectableFields(fields); } \
#else //ACDK_NOMETAINFO
#define DECL_ACDK_DUMMYMETACLASS
#define DECL_ACDK_DEFAULT_METACLASS(Super)
#endif //ACDK_NOMETAINFO
/**
include this token at top in an header, which doesn't contain any
meta info related declarations
The acdkmc doesn't try to parse the header any more.
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_NO_METAINFO_HEADER
/**
used to tag a class as a ACDK-class.
Normally you should not need this macro
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_CLASS
/**
used to tag a class as a ACDK-Interface.
Normally you should not need this macro
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_INTERFACE
/**
used to tag a field as not serializable, cloneable, etc
You can also use the keyword mutable
@ingroup acdkmacros
@ingroup acdkmetainfo
*/
#define ACDK_MUTABLE
/**
used to tag a field as not serializable
@ingroup acdkmetainfo
@ingroup acdkkeywords
*/
#define transient
/**
use to tag classes, methods or arguments as
not compatible with ACDK.
For theses classes/methods no metainformation will be created
@ingroup acdkmetainfo
@ingroup acdkkeywords
*/
#define foreign
/**
use to tag classes or methods not to generate
dmi proxy for this class/method
@ingroup acdkmetainfo
@ingroup acdkkeywords
*/
#define final
/**
ACDK_DECL_ENUM is only used as hint for acdkmc to
detect enumeration types, which are declared in
another header
@ingroup acdkmetainfo
*/
#define ACDK_DECL_ENUM(EnumType)
/**
Same as ACDK_DECL_ENUM but allows to fully qualify
the enumeration type.
another header
@ingroup acdkmetainfo
*/
#define ACDK_DECL_ENUM_FQ(NameSpace, EnumType)
/**
methods, tagged as overwrite will generate
DmiProxy methods, but no metainfo, because the metainfo
from a base class can be used.
@ingroup acdkmetainfo
@ingroup acdkkeywords
*/
#define overwrite virtual
#ifndef upcast_explicit
# if _MSC_VER >= 1300
# define upcast_explicit explicit
# else
/FONT>
# define upcast_explicit
# endif
/FONT>
#endif
/FONT>
/**
Convert acdk::lang::Object allocated on Stack or static into a RefHolder.
Prevents from deleting, if Reference count is 0
@ingroup acdksmartptr
*/
template <class RT, class T>
RT asStackRef(const T& obj)
{
obj.setStackRef(true);
return RT(const_cast<T*>(&obj));
}
/**
SR(Type, object) is just a more brief macro for the template:
template <class RT, class T> RT asStackRef(const T& obj)
@ingroup acdksmartptr
*/
#define SR(Type, obj) asStackRef<R##Type, Type>(obj)
/**
fully qualified version of macro SR(Type, obj)
@ingroup acdksmartptr
*/
#define SR_FQ(ns, Type, obj) asStackRef<ns R##Type, ns Type>(obj)
/**
A Proxy for synchronized access to acdk::lang::Object.
operator->() return pointer to acdk::lang::Object
@ingroup acdksmartptr
*/
template <class T>
class LockedProxy
{
T* _obj;
public:
LockedProxy(T* obj)
: _obj(obj)
{
_obj->lock();
}
~LockedProxy()
{
_obj->unlock();
}
T* operator->() { return _obj; }
const T* operator->() const { return _obj; }
};
#ifdef IN
# undef IN
#endif
/FONT>
#ifdef OUT
# undef OUT
#endif
/FONT>
#ifdef INOUT
# undef INOUT
#endif
/FONT>
/**
Tag an argument for sending the acdk::lang::Object by Reference from Client to Server.
Type can be a type of acdk::lang::Object or supported basic type.
@ingroup acdkkeywords
*/
#define IN(type) const type &
/**
Same as macro IN(type)
@ingroup acdkkeywords
*/
#define INP(type) const type &
/**
Tag an argument as output parameter .
Type can be a type of acdk::lang::Object or supported basic type.
@ingroup acdkkeywords
*/
#define OUT(type) type&
/**
Same as macro OUT(type)
@ingroup acdkkeywords
*/
#define OUTP(type) type&
/**
Tag an argument for send/receive it.
Type can be a type of acdk::lang::Object or supported basic type.
@ingroup acdkkeywords
*/
#define INOUT(type) type&
/**
Same as INOUT(type)
@ingroup acdkkeywords
*/
#define INOUTP(type) type&
/**
Used for performance improvemnts for return values.
return a reference of val, not a copy
(Must be non const, otherwise operator-> doesn't work)
@ingroup acdkkeywords
*/
#define RETOUT(val) OUT(val)
/**
Alias to RETOUT(val)
@ingroup acdkkeywords
*/
#define OUTRET(val) OUT(val)
/**
Transfer parameter by value from caller to callee.
These defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYVAL(T) IN(T)
/**
Transfer parameter by value from caller to callee.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYVALIN(T) IN(T) //::acdk::lang::dmi::TSendMarshaler<T>
/**
Transfer parameter by value from calee to caller.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYVALOUT(T) OUT(T) //old ::acdk::lang::dmi::TReceiveMarshaler<T>
/**
Transfer parameter by value from caller to callee and back.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYVALINOUT(T) INOUT(T) //old ::acdk::lang::dmi::TSendReceiveMarshaler<T>
/**
Transfer parameter by reference from caller to callee.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYREF(T) IN(T)
/**
Transfer parameter by reference from caller to callee.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYREFIN(T) IN(T)
/**
Transfer parameter by reference from callee to caller.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYREFOUT(T) OUT(T)
/**
Transfer parameter by reference from caller to callee and back.
these defined are only used as hints to acdkmc in case of remoting
@ingroup acdkkeywords
*/
#define BYREFINOUT(T) INOUT(T)
#endif // acdk_lang_sys_RefHolder_h
|