//===========================================================================// // File: MArray.hpp // // Contents: // //---------------------------------------------------------------------------// // Copyright (C) Microsoft Corporation. All rights reserved. // //===========================================================================// #pragma once #include "Stuff.hpp" namespace Stuff { //########################################################################## //########################## StaticArrayOf ########################### //########################################################################## template class StaticArrayOf #if defined(_ARMOR) : public Stuff::Signature #endif { public: StaticArrayOf(); StaticArrayOf(const StaticArrayOf&); StaticArrayOf(const T &value); StaticArrayOf(T *data, size_t length); ~StaticArrayOf(); void TestInstance() const {} StaticArrayOf& operator=(const StaticArrayOf&); T& operator[](size_t i); const T& operator[](size_t i) const; void AssignValue(const T &value); void AssignData(const T *data, size_t length); size_t GetLength() const {return N;} size_t GetSize() const {return N * sizeof(T);} T* GetData() {return data;} const T* GetData() const {return data;} #if 0 bool Compare(const StaticArrayOf&); #endif friend MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const StaticArrayOf *array ); friend MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, StaticArrayOf *array ); private: T data[N]; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template inline StaticArrayOf::StaticArrayOf() { } template inline StaticArrayOf::StaticArrayOf(const StaticArrayOf &array) { AssignData(array.data, N); } template inline StaticArrayOf::StaticArrayOf(const T &value) { AssignValue(value); } template inline StaticArrayOf::StaticArrayOf(T *data_to_copy, size_t length) { AssignData(data_to_copy, length); } template inline StaticArrayOf::~StaticArrayOf() { } template StaticArrayOf& StaticArrayOf::operator=(const StaticArrayOf &array) { if (this != &array) { AssignData(&array.data[0], N); } return *this; } template inline T& StaticArrayOf::operator[](size_t i) { Verify(i < N); return data[i]; } template inline const T& StaticArrayOf::operator[](size_t i) const { Verify(i < N); return data[i]; } template void StaticArrayOf::AssignValue(const T &value) { // Do not memcopy, object semantics may be required for (int i = 0; i < N; i++) data[i] = value; } template void StaticArrayOf::AssignData(const T *data_to_copy, size_t length) { Check_Pointer(data_to_copy); Verify(length <= N); // Do not memcopy, object semantics may be required for (int i = 0; i < length; i++) data[i] = data_to_copy[i]; } #if 0 template bool StaticArrayOf::Compare(const StaticArrayOf &array) { if (N != array.GetLength()) return false; for (int i = 0; i < N; i++) { if (data[i] != array.data[i]) return false; } return true; } #endif template MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const StaticArrayOf *array ) { Check_Object(stream); Check_Pointer(array); return stream->WriteBytes(&array->data[0], N * sizeof(T)); } template MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, StaticArrayOf *array ) { Check_Object(stream); Check_Pointer(array); return stream->ReadBytes(&array->data[0], N * sizeof(T)); } //########################################################################## //######################### DynamicArrayOf ########################### //########################################################################## template class DynamicArrayOf #if defined(_ARMOR) : public Stuff::Signature #endif { public: DynamicArrayOf(); DynamicArrayOf(const DynamicArrayOf&); DynamicArrayOf(size_t length); DynamicArrayOf(const T &value, size_t length); DynamicArrayOf(const T *data, size_t length); ~DynamicArrayOf(); void TestInstance() const {} void TestInstance() {} DynamicArrayOf& operator=(const DynamicArrayOf&); T& operator[](size_t i); const T& operator[](size_t i) const; void AssignValue(const T &value, size_t length); void AssignData(const T *data, size_t length); size_t GetLength() const {return length;} void SetLength(size_t length); size_t GetSize() const {return length * sizeof(T);} T* GetData() {return data;} const T* GetData() const {return data;} #if 0 bool Compare(const DynamicArrayOf&); #endif friend MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const DynamicArrayOf *array ); friend MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, DynamicArrayOf *array ); private: void SetStorageLength(size_t length); void CopyArray(const DynamicArrayOf&); T *data; size_t length; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ template DynamicArrayOf::DynamicArrayOf() { data = NULL; length = 0; } template DynamicArrayOf::DynamicArrayOf(const DynamicArrayOf &array) { data = NULL; length = 0; CopyArray(array); } template DynamicArrayOf::DynamicArrayOf(size_t length_to_set) { data = NULL; length = 0; SetStorageLength(length_to_set); Verify(length == length_to_set); #if defined(_ARMOR) if (length_to_set > 0) Check_Pointer(data); else Verify(!data); #endif } template DynamicArrayOf::DynamicArrayOf(const T &value, size_t length_to_set) { data = NULL; length = 0; AssignValue(value, length_to_set); } template DynamicArrayOf::DynamicArrayOf(const T *data_to_copy, size_t length_to_set) { data = NULL; length = 0; AssignData(data_to_copy, length_to_set); } template DynamicArrayOf::~DynamicArrayOf() { if (data != NULL) { Unregister_Pointer(data); delete[] data; } } template DynamicArrayOf& DynamicArrayOf::operator=(const DynamicArrayOf &array) { if (this != &array) CopyArray(array); return *this; } template inline T& DynamicArrayOf::operator[](size_t i) { Check_Pointer(data); Verify(i < length); return data[i]; } template inline const T& DynamicArrayOf::operator[](size_t i) const { Verify(i < length); return data[i]; } template void DynamicArrayOf::AssignValue(const T &value, size_t length_to_set) { SetStorageLength(length_to_set); // Do not memcopy, object semantics may be required for (int i = 0; i < length; i++) data[i] = value; } template void DynamicArrayOf::AssignData(const T *data_to_copy, size_t length_to_set) { Check_Pointer(data_to_copy); SetStorageLength(length_to_set); // Do not memcopy, object semantics may be required for (int i = 0; i < length; i++) data[i] = data_to_copy[i]; } template void DynamicArrayOf::SetLength(size_t length_to_set) { if (length_to_set != length) { if (length_to_set > 0) { T* new_data = new T[length_to_set]; Register_Pointer(new_data); if (data != NULL) { // Do not memcopy, object semantics may be required size_t i = Min(length_to_set, length); while (i--) new_data[i] = data[i]; Unregister_Pointer(data); delete[] data; } data = new_data; } else { Unregister_Pointer(data); delete[] data; data = NULL; } length = length_to_set; } } #if 0 template void DynamicArrayOf::Compare(const DynamicArrayOf &array) { if (length != array.length) return false; for (int i = 0; i < length; i++) { if (data[i] != array.data[i]) return false; } return true; } #endif template void DynamicArrayOf::SetStorageLength(size_t length_to_set) { if (length_to_set != length) { if (length_to_set > 0) { if (data != NULL) { Unregister_Pointer(data); delete[] data; } length = length_to_set; data = new T[length]; Register_Pointer(data); } else { Verify(length_to_set == 0); Unregister_Pointer(data); delete[] data; data = NULL; } } } template void DynamicArrayOf::CopyArray(const DynamicArrayOf &array) { if (array.length > 0) { Check_Pointer(array.data); AssignData(&array.data[0], array.length); } else { Verify(array.length == 0); Verify(array.data == NULL); if (data != NULL) { Unregister_Pointer(data); delete[] data; length = 0; } } } template MemoryStream& MemoryStreamIO_Write( MemoryStream *stream, const DynamicArrayOf *array ) { Check_Object(stream); Check_Pointer(array); size_t length = array->length; MemoryStreamIO::Write(stream, &length); if (length > 0) stream->WriteBytes(&array->data[0], length * sizeof(T)); return *stream; } template MemoryStream& MemoryStreamIO_Read( MemoryStream *stream, DynamicArrayOf *array ) { Check_Object(stream); Check_Pointer(array); size_t length; MemoryStreamIO::Read(stream, &length); array->SetLength(length); Verify(length == array->length); if (length > 0) stream->ReadBytes(&array->data[0], length * sizeof(T)); return *stream; } }