/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017 Raytrix GmbH. All rights reserved.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once

#include "DllInterface.h"
#include "Rx.Interop.Runtime30/IMemory.h"

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// namespace: Rx
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
namespace Rx
{
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// 	Generic array class.
	/// </summary>
	///
	/// <typeparam name="TValue"> Generic type parameter. </typeparam>
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	template<typename TValue>
	class CRxArray : public Rx::Interop::Runtime30::IMemory
	{
	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Default constructor. Creates an empty array.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Constructor. Creates a new array with the given number of default-constructed elements.
		/// </summary>
		///
		/// <param name="nElementCount"> The number of elements. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray(size_t nElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Constructor. Constructs a new array with nElementCount copies of elements with value tInitValue.
		/// </summary>
		///
		/// <param name="nElementCount"> The number of elements. </param>
		/// <param name="tInitValue">    The initial value of each element in this array. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray(size_t nElementCount, const TValue& tInitValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copy constructor. Creates a copy of the given array.
		/// </summary>
		///
		/// <param name="xArray"> The array to copy. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray(const CRxArray<TValue>& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Move constructor.
		/// </summary>
		///
		/// <param name="xArray"> [in,out] The array to move. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray(CRxArray<TValue>&& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Creates a new array by moving or copying the internal data into this array.
		/// </summary>
		///
		/// <param name="pvInternal"> [in,out] Pointer to the internal data. </param>
		/// <param name="bMove">	  True to move the data, false to copy the data. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray(void* pvInternal, bool bMove);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Destructs the array.
		///
		/// 	The destructor of the elements are called and the used storage is deallocated. Note, that if the elements are pointers,
		/// 	the pointed-to objects are not destroyed.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual ~CRxArray();

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Replaces the contents with nElementCount copies of value tInitValue.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Assign(size_t nElementCount, const TValue& tInitValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the element at the specified index, with bounds checking. If nIndex is not within the range of
		/// 	the array, an exception is thrown.
		/// </summary>
		///
		/// <param name="nIndex"> The index. </param>
		///
		/// <returns> Reference to the requested element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue& At(size_t nIndex);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the element at the specified index, with bounds checking. If nIndex is not within the range of
		/// 	the array, an exception is thrown.
		/// </summary>
		///
		/// <param name="nIndex"> The index. </param>
		///
		/// <returns> Reference to the requested element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue& At(size_t nIndex) const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the first element in the array. Calling Front on an empty array is undefined.
		/// </summary>
		///
		/// <returns> Reference to the first element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue& Front();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the first element in the array. Calling Front on an empty array is undefined.
		/// </summary>
		///
		/// <returns> Reference to the first element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue& Front() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the last element in the array. Calling Back on an empty array is undefined.
		/// </summary>
		///
		/// <returns> Reference to the last element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue& Back();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the last element in the array. Calling Back on an empty array is undefined.
		/// </summary>
		///
		/// <returns> Reference to the last element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue& Back() const;

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Checks if the array has no elements.
		/// </summary>
		///
		/// <returns> True if the array is empty, false otherwise. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		bool IsEmpty() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns the number of elements in the array.
		/// </summary>
		///
		/// <returns> The number of elements in the array. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		size_t Size() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Increase the capacity of the array to a value that's greater or equal to nNewElementCount. If nNewElementCount is
		/// 	greater than the current capacity, new storage is allocated, otherwise the method does nothing.
		///
		/// 	If nNewElementCount is greater than capacity, all iterators, including the past-the-end iterator, and all references to
		/// 	the elements are invalidated. Otherwise, no iterators or references are invalidated.
		/// </summary>
		///
		/// <remarks>
		/// 	Reserve cannot be used to reduce the capacity of the array, to that end ShrinkToFit() is provided.
		///
		/// 	Correctly using Reserve can prevent unnecessary reallocations, but inappropriate uses of Reserve (for instance, calling
		/// 	it before every PushBack() call) may actually increase the number of reallocations (by causing the capacity to grow
		/// 	linearly rather than exponentially) and result in increased computational complexity and decreased performance.
		/// </remarks>
		///
		/// <param name="nNewElementCount"> The new element count. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Reserve(size_t nNewElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns the number of elements that the array has currently allocated space for.
		/// </summary>
		///
		/// <returns> Capacity of the currently allocated storage. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		size_t Capacity() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Requests the removal of unused capacity.
		///
		/// 	It is a non-binding request to reduce Capacity() to Size(). It depends on the implementation if the request is fulfilled.
		///
		/// 	If reallocation occurs, all iterators, including the past the end iterator, and all references to the elements are
		/// 	invalidated. If no reallocation takes place, no iterators or references are invalidated.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void ShrinkToFit();

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Removes all elements from the array.
		///
		/// 	Invalidates any references, pointers, or iterators referring to contained elements. Any past-the-end iterators are
		/// 	also invalidated.
		///
		/// 	Leaves the Capacity() of the array unchanged.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Clear();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Inserts elements at the specified location in the array.
		///
		/// 	Causes reallocation if the new size is greater than the old capacity. If the new size is greater than capacity, all
		/// 	iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point
		/// 	remain valid. The past-the-end iterator is also invalidated.
		/// </summary>
		///
		/// <param name="nPosition"> The position. </param>
		/// <param name="tValue">    The value. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Insert(size_t nPosition, const TValue& tValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Inserts elements at the specified location in the array.
		///
		/// 	Causes reallocation if the new size is greater than the old capacity. If the new size is greater than capacity, all
		/// 	iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point
		/// 	remain valid. The past-the-end iterator is also invalidated.
		/// </summary>
		///
		/// <param name="nPosition"> The position. </param>
		/// <param name="tValue">    [in,out] The value to move. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Insert(size_t nPosition, TValue&& tValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Inserts nCount copies of tValue at the specified location in the array.
		///
		/// 	Causes reallocation if the new size is greater than the old capacity. If the new size is greater than capacity, all
		/// 	iterators and references are invalidated. Otherwise, only the iterators and references before the insertion point
		/// 	remain valid. The past-the-end iterator is also invalidated.
		/// </summary>
		///
		/// <param name="nPosition"> The position. </param>
		/// <param name="tValue">    The value. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Insert(size_t nPosition, size_t nCount, const TValue& tValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Removes the element at the given position from the array.
		/// </summary>
		///
		/// <param name="nPosition"> The position. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Erase(size_t nPosition);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Removes specified elements from the array.
		/// </summary>
		///
		/// <param name="nPosition"> The position. </param>
		/// <param name="nCount">    Number of elements to remove. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Erase(size_t nPosition, size_t nCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Appends the given element value to the end of the array. The new element is initialized as a copy of tValue.
		///
		/// 	If the new size is greater than capacity then all iterators and references (including the past-the-end iterator)
		/// 	are invalidated. Otherwise only the past-the-end iterator is invalidated.
		/// </summary>
		///
		/// <param name="tValue"> The value of the element to append. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void PushBack(const TValue& tValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Appends the given element value to the end of the array. The value is moved into the new element.
		///
		/// 	If the new size is greater than capacity then all iterators and references (including the past-the-end iterator)
		/// 	are invalidated. Otherwise only the past-the-end iterator is invalidated.
		/// </summary>
		///
		/// <param name="tValue"> [in,out] The value of the element to append. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void PushBack(TValue&& tValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Removes the last element of the array. Calling PopBack on an empty array is undefined.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void PopBack();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Resizes the array to contain count elements.
		///
		/// 	If the current size is greater than nNewElementCount, the array is reduced to its first nNewElementCount elements.
		///
		/// 	If the current size is less than count, additional copies of tValue are appended.
		/// </summary>
		///
		/// <param name="nNewElementCount"> New size of the array. </param>
		/// <param name="tValue">		    The value to initialize the new elements with. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Resize(size_t nNewElementCount, const TValue& tValue);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Exchanges the contents of the array with those of xArray. Does not invoke any move, copy, or swap operations on
		/// 	individual elements.
		/// </summary>
		///
		/// <param name="xArray"> [in,out] The array to exchange the contents with. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void Swap(CRxArray<TValue>& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copies this array into the internal data.
		/// </summary>
		///
		/// <param name="pvInternal"> [in,out] Pointer to the internal data. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void CopyIntoInternal(void* pvInternal) const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Creates a new array by copying the internal data into this array.
		/// </summary>
		///
		/// <param name="pvInternal"> [in,out] Pointer to the internal data. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void CopyFromInternal(const void* pvInternal);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	moves this array into the internal data. This array is empty afterwards.
		/// </summary>
		///
		/// <param name="pvInternal"> [in,out] Pointer to the internal data. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void MoveIntoInternal(void* pvInternal);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Creates a new array by moving the internal data into this array.
		/// </summary>
		///
		/// <param name="pvInternal"> [in,out] Pointer to the internal data. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		void MoveFromInternal(void* pvInternal);

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns an iterator (pointer) to the first element of the array.
		/// </summary>
		///
		/// <returns> Iterator to the first element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue* begin();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns an iterator (pointer) to the first element of the array.
		/// </summary>
		///
		/// <returns> Iterator to the first element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue* begin() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns an iterator (pointer) to the element following the last element of the array. This element acts as a
		/// 	placeholder; attempting to access it results in undefined behavior.
		/// </summary>
		///
		/// <returns> Iterator to the element following the last element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue* end();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns an iterator (pointer) to the element following the last element of the array. This element acts as a
		/// 	placeholder; attempting to access it results in undefined behavior.
		/// </summary>
		///
		/// <returns> Iterator to the element following the last element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue* end() const;

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copy assignment operator. Replaces the contents with a copy of the contents of the given array.
		/// </summary>
		///
		/// <param name="xArray"> The array to copy. </param>
		///
		/// <returns> This array. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray<TValue>& operator=(const CRxArray<TValue>& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Move assignment operator. Replaces the contents with those of the given array using move semantics (i.e. the data in
		/// 	the given array is moved  into this array). The given array is in a valid but unspecified state afterwards.
		/// </summary>
		///
		/// <param name="xArray"> [in,out] The array to move. </param>
		///
		/// <returns> This array. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		CRxArray<TValue>& operator=(CRxArray<TValue>&& xArray);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the element at the specified index. No bounds checking is performed.
		/// </summary>
		///
		/// <param name="nIndex"> The index. </param>
		///
		/// <returns> Reference to the requested element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue& operator[](size_t nIndex);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Returns a reference to the element at the specified index. No bounds checking is performed.
		/// </summary>
		///
		/// <param name="nIndex"> The index. </param>
		///
		/// <returns> Reference to the requested element. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue& operator[](size_t nIndex) const;

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		TValue* Data();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		const TValue* Data() const;

		/************************************************************************/
		/* Rx::Interop::Runtime30::IMemory                                      */
		/************************************************************************/

	public:

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Resizes the array to contain count elements.
		///
		/// 	If the current size is greater than nNewElementCount, the array is reduced to its first nNewElementCount elements.
		///
		/// 	If the current size is less than count, additional default-inserted elements are appended.
		/// </summary>
		///
		/// <param name="nNewElementCount"> Number of new elements. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void New(size_t nElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Resizes the array to contain count elements.
		///
		/// 	If the current size is greater than nNewElementCount, the array is reduced to its first nNewElementCount elements.
		///
		/// 	If the current size is less than count, additional default-inserted elements are appended.
		/// </summary>
		///
		/// <param name="nNewElementCount"> Number of new elements. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Resize(size_t nNewElementCount);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Removes all elements from the array.
		///
		/// 	Invalidates any references, pointers, or iterators referring to contained elements. Any past-the-end iterators are
		/// 	also invalidated.
		///
		/// 	Leaves the Capacity() of the array unchanged.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Delete();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Sets the internal memory to zeros.
		/// </summary>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void Reset();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Copies the content of the given source memory into this array. Sets the size of this array to the size of the memory.
		/// </summary>
		///
		/// <param name="pxSrcMemory"> The source memory. </param>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void CopyFrom(const IMemoryAccess* pxSrcMemory);

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual void* GetPointer();

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the pointer to the internal data.
		/// </summary>
		///
		/// <returns> The pointer. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual const void* GetPointer() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the size of a single value in this array.
		/// </summary>
		///
		/// <returns> The element size. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual size_t GetElementSize() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Gets the number of elements in this array.
		/// </summary>
		///
		/// <returns> The length. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual size_t Length() const;

		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		/// 	Query if this object is valid. Returns always true.
		/// </summary>
		///
		/// <returns> True if valid, false if not. </returns>
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		virtual bool IsValid() const;

	protected:

		void* m_pvVector;
	};
}

/************************************************************************/
/* Explicit Exports                                                     */
/************************************************************************/

// Only set the extern keyword, when they template specializations are exported
#ifdef RXCOREEX_EXPORTS
	#define EXTERN
#else
	#define EXTERN extern
#endif

EXTERN template class RXCOREEX_API Rx::CRxArray<char>;
EXTERN template class RXCOREEX_API Rx::CRxArray<unsigned char>;
EXTERN template class RXCOREEX_API Rx::CRxArray<short>;
EXTERN template class RXCOREEX_API Rx::CRxArray<unsigned short>;
EXTERN template class RXCOREEX_API Rx::CRxArray<int>;
EXTERN template class RXCOREEX_API Rx::CRxArray<unsigned int>;
EXTERN template class RXCOREEX_API Rx::CRxArray<float>;
EXTERN template class RXCOREEX_API Rx::CRxArray<double>;

#include "Rx.Core/RxString.h"
EXTERN template class RXCOREEX_API Rx::CRxArray<Rx::CRxString>;

// Import implementation if this header is included by its own project
#ifdef RXCOREEX_EXPORTS
    #include "RxArray.cxx"
#endif
