Collection.h revision 0010ccca43c2554000fdd0572c7b9cf5ad17ac91
/** @file
*
* VirtualBox collection templates
*/
/*
* Copyright (C) 2006-2007 innotek GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License as published by the Free Software Foundation,
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
* distribution. VirtualBox OSE is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY of any kind.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
#ifndef ____H_COLLECTION
#define ____H_COLLECTION
#include "VirtualBoxBase.h"
#include <list>
#include <vector>
/**
* Template class to create a non-thread safe implementation of the
* enumerator over the read-only collection that stores safe interface pointers
* using std::vector. The enumerator is attached to an existing std::vector
* storing EnumItem instances, optionally making a copy.
*
* The template also inherits the VirtualBoxSupportErrorInfoImpl template and
* therefore provides the error info support.
*
* @param IEnum
* enumerator interface to implement. This interface must define
* HasMore (BOOL *) and GetNext (IEnumItem **).
* @param IEnumItem
* enumerator item interface. Pointers of this type are returned
* by GetNext().
* @param EnumItem
* actual enumerator item class. Instances of this class
* are stored in the std::vector passed as an argument to
* init(). This class must be a ComPtrBase<> template instantiation
* or derived from such instantiation.
* @param ComponentClass
* the only role of this class is to have the following member:
* |public: static const wchar_t *getComponentName()|, that returns the
* component name (see VirtualBoxSupportErrorInfoImpl template for more info).
*/
#ifdef RT_OS_WINDOWS
#else
#endif
{
{
allocated = true;
}
{
if (parent)
}
// public initializer/uninitializer for internal purposes only
{
parent = p;
if (parent)
if (readonly)
vec = &v;
else
}
{
if (!more)
return E_POINTER;
return S_OK;
}
{
if (!next)
return E_POINTER;
"IfaceVectorEnumerator", "No more elements"));
++iter;
}
// for VirtualBoxSupportErrorInfoImpl
inline static const wchar_t *getComponentName() {
return ComponentClass::getComponentName();
}
bool allocated;
};
/**
* Template class to create a non-thread safe implementation of the
* read-only collection that stores interface pointers. The collection is
* initialized from the std::list storing CollItem instances by copying
* (i.e. making a snapshot of) all list items to std::vector for
* optimized random access.
*
* The template also inherits the VirtualBoxSupportErrorInfoImpl template and
* therefore provides the error info support.
*
* @param IColl
* collection interface to implement. This interface must define
* Count(ULONG *), GetItemAt (ULONG, ICollItem**) and Enumerate (IEnum **).
* @param ICollItem
* collection item interface. Pointers of this type are returned by
* GetItemAt().
* @param IEnum
* enumerator interface. Pointers of this type are returned by Enumerate().
* @param CollItem
* actual collection item class. Instances of this class
* are stored in the std::list passed as an argument to
* init() and in the internal std::vector. This class must be a
* ComPtrBase<> template instantiation or derived from such instantiation.
* @param Enum
* enumerator implementation class used to construct a new enumerator.
* This class must be a IfaceVectorEnumerator<> template instantiation
* with IEnum and IEnumItem arguments exactly the same as in this template,
* and with EnumItem argument exactly the same as this template's
* CollItem argument.
* @param ComponentClass
* the only role of this class is to have the following member:
* |public: static const wchar_t *getComponentName()|, that returns the
* component name (see VirtualBoxSupportErrorInfoImpl template for more info).
*/
#ifdef RT_OS_WINDOWS
#else
#endif
{
// public initializer/uninitializer for internal purposes only
{
// create a copy of the list
}
{
if (!count)
return E_POINTER;
return S_OK;
}
{
if (!item)
return E_POINTER;
"ReadonlyIfaceVector", "The specified index is out of range"));
}
{
if (!enumerator)
return E_POINTER;
*enumerator = NULL;
{
}
return rc;
}
// for VirtualBoxSupportErrorInfoImpl
inline static const wchar_t *getComponentName() {
return ComponentClass::getComponentName();
}
};
/**
* This macro declares an enumerator class and a collection class that stores
* elements of the given class @a itemcls that implements the given
* interface @a iface
*
* The the @a itemcls class must be either a ComObjPtr or a ComPtr template
* instantiation with the argument being a class that implements the @a iface
* interface.
*
* The namespace of the collection class remains opened after
* this macro is expanded (i.e. no closing brace with semicolon), which
* allows to declare extra collection class members. This namespace
* must be closed by the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END macro.
*
* For example, given |ComObjPtr <OSomeItem>|, |ISomeItem|| and |OSomeItem|
* arguments, this macro will generate the following code:
*
* <code>
* class OSomeItemEnumerator : public
* IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <OSomeItem>,
* OSomeItemEnumerator>
* {...};
* class SomeItemCollection : public
* ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <OSomeItem>,
* OSomeItemEnumerator, OSomeItemCollection>
* {...};
* </code>
*
* i.e. it assumes that ISomeItemEnumerator, ISomeItem and ISomeItemCollection
* are existing interfaces, and OSomeItem implements the ISomeItem interface.
* It also assumes, that std::list passed to SomeItemCollection::init()
* stores objects of the @a itemcls class (|ComObjPtr <OSomeItem>| in the
* example above).
*
* See descriptions of the above IfaceVectorEnumerator and
* ReadonlyIfaceVector templates for more info.
*
* The generated class also inherits the VirtualBoxSupportTranslation template,
* providing the support for translation of string constants within class
* members.
*
* The macro is best to be placed in the header after SomeItem class
* declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END macro must
* follow all extra member declarations of the collection class, or right
* after this macro if the collection doesn't have extra members.
*
* @param itemcls Either ComObjPtr or ComPtr for the class that implements
* the given interface of items to be stored in the
* collection
* @param iface Interface of items implemented by the @a itemcls class
* @param prefix Prefix to apply to generated enumerator and collection
* names.
*/
{ \
} \
}; \
prefix##Collection> \
{ \
}
/**
* This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN
* and must be always used to finalize the collection declaration started
* by that macro.
*
* Currently the macro just expands to the closing brace with semicolon,
* but this might change in the future.
*/
};
/**
* This is a "shortcut" macro, for convenience. It expands exactly to:
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN(itemcls, iface, prefix)
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END(itemcls, iface, prefix)
* </code>
*/
/**
* This macro declares an enumerator class and a collection class for the
* given item class @a c.
*
* It's a convenience macro that deduces all arguments to the
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro from a single @a c
* class name argument. Given a class named |SomeItem|, this macro is
* equivalent to
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComObjPtr <SomeItem>, ISomeItem, SomeItem)
* </code>
* and will generate the following code:
* <code>
* class OSomeItemEnumerator : public
* IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComObjPtr <SomeItem>,
* SomeItemEnumerator>
* {...};
* class SomeItemCollection : public
* ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComObjPtr <SomeItem>,
* SomeItemEnumerator, SomeItemCollection>
* {...};
* </code>
*
* See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
* description.
*
* The macro is best to be placed in the header after SomeItem class
* declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_END macro must follow
* all extra member declarations of the collection class, or right after this
* macro if the collection doesn't have extra members.
*
* @param c Component class implementing the interface of items to be stored
* in the collection
*/
#define COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c) \
COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComObjPtr <c>, I##c, c)
/**
* This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN
* and must be always used to finalize the collection declaration started
* by that macro.
*
* This is a "shortcut" macro that expands exactly to:
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
* </code>
*/
#define COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c) \
COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
/**
* This is a "shortcut" macro, for convenience. It expands exactly to:
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN(c)
* COM_DECL_READONLY_ENUM_AND_COLLECTION_END(c)
* </code>
*/
#define COM_DECL_READONLY_ENUM_AND_COLLECTION(c) \
/**
* This macro declares an enumerator class and a collection class for the
* given item interface @a iface prefixed with the given @a prefix.
*
* It's a convenience macro that deduces all arguments to the
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN macro from the two given
* @a iface and @a prefix arguments. Given an interface named |ISomeItem|,
* and a prefix SomeItem this macro is equivalent to
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN (ComPtr <ISomeItem>, ISomeItem, SomeItem)
* </code>
* and will generate the following code:
* <code>
* class OSomeItemEnumerator : public
* IfaceVectorEnumerator <ISomeItemEnumerator, ISomeItem, ComPtr <ISomeItem>,
* SomeItemEnumerator>
* {...};
* class SomeItemCollection : public
* ReadonlyIfaceVector <ISomeItemCollection, ISomeItem, ComPtr <ISomeItem>,
* SomeItemEnumerator, SomeItemCollection>
* {...};
* </code>
*
* See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
* description.
*
* The macro is best to be placed in the header after SomeItem class
* declaration. The COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macro must follow
* all extra member declarations of the collection class, or right after this
* macro if the collection doesn't have extra members.
*
* @param prefix Prefix prepended to the generated collection and
* enumerator classes
* @param iface Interface class
*/
/**
* This macro is a counterpart to COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN
* and must be always used to finalize the collection declaration started
* by that macro.
*
* This is a "shortcut" macro that expands exactly to:
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_END (ComObjPtr <c>, I##c, c)
* </code>
*/
/**
* This is a "shortcut" macro, for convenience. It expands exactly to:
* <code>
* COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN(c)
* COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END(c)
* </code>
*/
#ifdef RT_OS_WINDOWS
#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c)
#else // !RT_OS_WINDOWS
/**
* This macro defines nsISupports implementations (i.e. QueryInterface(),
* AddRef() and Release()) for the enumerator and collection classes
* declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_EX,
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN and
* COM_DECL_READONLY_ENUM_AND_COLLECTION_EX macros.
*
* See COM_DECL_READONLY_ENUM_AND_COLLECTION_EX_BEGIN for the detailed
* description.
*
* The macro should be placed in one of the source files.
*
* @note
* this macro is XPCOM-specific and not necessary for MS COM,
* so expands to nothing on Win32.
*
* @param itemcls Either ComObjPtr or ComPtr for the class that implements
* the given interface of items to be stored in the
* collection
* @param iface Interface of items implemented by the @a itemcls class
* @param prefix Prefix to apply to generated enumerator and collection
* names.
*/
/**
* This macro defines nsISupports implementations (i.e. QueryInterface(),
* AddRef() and Release()) for the enumerator and collection classes
* declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION,
* COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN and
* COM_DECL_READONLY_ENUM_AND_COLLECTION_END macros.
*
* See COM_DECL_READONLY_ENUM_AND_COLLECTION_BEGIN for the detailed
* description.
*
* The macro should be placed in one of the source files.
*
* @note
* this macro is XPCOM-specific and not necessary for MS COM,
* so expands to nothing on Win32.
*
* @param c Component class implementing the interface of items to be stored
* in the collection
*/
#define COM_IMPL_READONLY_ENUM_AND_COLLECTION(c) \
COM_IMPL_READONLY_ENUM_AND_COLLECTION_EX (0, I##c, c)
/**
* This macro defines nsISupports implementations (i.e. QueryInterface(),
* AddRef() and Release()) for the enumerator and collection classes
* declared by the COM_DECL_READONLY_ENUM_AND_COLLECTION_AS,
* COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN and
* COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_END macros.
*
* See COM_DECL_READONLY_ENUM_AND_COLLECTION_AS_BEGIN for the detailed
* description.
*
* The macro should be placed in one of the source files.
*
* @note
* this macro is XPCOM-specific and not necessary for MS COM,
* so expands to nothing on Win32.
*
* @param prefix Prefix prepended to the generated collection and
* enumerator classes
* @param iface Interface class
*/
#endif // !RT_OS_WINDOWS
#endif // ____H_COLLECTION