Use MVKVector whenever possible in MoltenVK, especially within render loop.

Minor fixes and extensions to MVKVector implementations.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 15bcbe5..a3a2ce3 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -21,6 +21,7 @@
 - Revert to supporting host-coherent memory for linear images on macOS.
 - Ensure Vulkan loader magic number is set every time before returning any dispatchable Vulkan handle.
 - Consolidate the various linkable objects into a `MVKLinkableMixin` template base class.
+- Use `MVKVector` whenever possible in MoltenVK, especially within render loop.
 
 
 MoltenVK 1.0.36
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
index 9213901..036605c 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdDispatch.h
@@ -20,7 +20,6 @@
 
 #include "MVKCommand.h"
 #include "MVKMTLResourceBindings.h"
-#include <vector>
 
 #import <Metal/Metal.h>
 
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
index d5bf3dd..1cfd37e 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.h
@@ -20,7 +20,6 @@
 
 #include "MVKCommand.h"
 #include "MVKVector.h"
-#include <vector>
 
 class MVKCommandBuffer;
 class MVKPipeline;
@@ -54,9 +53,9 @@
 	VkPipelineStageFlags _srcStageMask;
 	VkPipelineStageFlags _dstStageMask;
 	VkDependencyFlags _dependencyFlags;
-	std::vector<VkMemoryBarrier> _memoryBarriers;
-	std::vector<VkBufferMemoryBarrier> _bufferMemoryBarriers;
-	std::vector<VkImageMemoryBarrier> _imageMemoryBarriers;
+	MVKVectorInline<VkMemoryBarrier, 4> _memoryBarriers;
+	MVKVectorInline<VkBufferMemoryBarrier, 4> _bufferMemoryBarriers;
+	MVKVectorInline<VkImageMemoryBarrier, 4> _imageMemoryBarriers;
 };
 
 
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
index 18fe127..c65adce 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdPipeline.mm
@@ -77,7 +77,7 @@
 													  afterStages: srcStages
 													 beforeStages: dstStages];
 		}
-		std::vector<id<MTLResource>> resources;
+		MVKVectorInline<id<MTLResource>, 16> resources;
 		resources.reserve(_bufferMemoryBarriers.size() + _imageMemoryBarriers.size());
 		for (auto& mb : _bufferMemoryBarriers) {
 			auto* mvkBuff = (MVKBuffer*)mb.buffer;
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
index 2658c0f..0f84ff0 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdRenderPass.h
@@ -20,7 +20,6 @@
 
 #include "MVKCommand.h"
 #include "MVKVector.h"
-#include <vector>
 
 #import <Metal/Metal.h>
 
@@ -85,7 +84,7 @@
 #pragma mark -
 #pragma mark MVKCmdExecuteCommands
 
-/** Vulkan command to end the current render pass. */
+/** Vulkan command to execute secondary command buffers. */
 class MVKCmdExecuteCommands : public MVKCommand {
 
 public:
@@ -96,7 +95,7 @@
 	MVKCmdExecuteCommands(MVKCommandTypePool<MVKCmdExecuteCommands>* pool);
 
 private:
-	std::vector<MVKCommandBuffer*> _secondaryCommandBuffers;
+	MVKVectorInline<MVKCommandBuffer*, 64> _secondaryCommandBuffers;
 };
 
 #pragma mark -
diff --git a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
index 231924a..a7b9486 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCmdTransfer.h
@@ -22,7 +22,7 @@
 #include "MVKMTLBufferAllocation.h"
 #include "MVKCommandResourceFactory.h"
 #include "MVKFoundation.h"
-#include <vector>
+#include "MVKVector.h"
 
 #import <Metal/Metal.h>
 
@@ -68,9 +68,9 @@
 	bool _isDstCompressed;
 	bool _canCopyFormats;
 	bool _useTempBuffer;
-	std::vector<VkImageCopy> _imageCopyRegions;
-	std::vector<VkBufferImageCopy> _srcTmpBuffImgCopies;
-	std::vector<VkBufferImageCopy> _dstTmpBuffImgCopies;
+	MVKVectorInline<VkImageCopy, 4> _imageCopyRegions;
+	MVKVectorInline<VkBufferImageCopy, 4> _srcTmpBuffImgCopies;
+	MVKVectorInline<VkBufferImageCopy, 4> _dstTmpBuffImgCopies;
 	size_t _tmpBuffSize;
     MVKCommandUse _commandUse;
 };
@@ -117,7 +117,7 @@
 	MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
 	MTLSamplerMinMagFilter _mtlFilter;
 	MVKRPSKeyBlitImg _blitKey;
-	std::vector<MVKImageBlitRender> _mvkImageBlitRenders;
+	MVKVectorInline<MVKImageBlitRender, 4> _mvkImageBlitRenders;
 };
 
 
@@ -157,11 +157,11 @@
     VkImageLayout _srcLayout;
     MVKImage* _dstImage;
     VkImageLayout _dstLayout;
-    std::vector<VkImageBlit> _expansionRegions;
-    std::vector<VkImageCopy> _copyRegions;
     MVKImageDescriptorData _transferImageData;
     MTLRenderPassDescriptor* _mtlRenderPassDescriptor;
-    std::vector<MVKMetalResolveSlice> _mtlResolveSlices;
+	MVKVectorInline<VkImageBlit, 4> _expansionRegions;
+	MVKVectorInline<VkImageCopy, 4> _copyRegions;
+	MVKVectorInline<MVKMetalResolveSlice, 4> _mtlResolveSlices;
 };
 
 
@@ -186,7 +186,7 @@
 
 	MVKBuffer* _srcBuffer;
 	MVKBuffer* _dstBuffer;
-	std::vector<VkBufferCopy> _mtlBuffCopyRegions;
+	MVKVectorInline<VkBufferCopy, 4> _mtlBuffCopyRegions;
 };
 
 
@@ -215,7 +215,7 @@
     MVKBuffer* _buffer;
     MVKImage* _image;
     VkImageLayout _imageLayout;
-    std::vector<VkBufferImageCopy> _bufferImageCopyRegions;
+	MVKVectorInline<VkBufferImageCopy, 4> _bufferImageCopyRegions;
     bool _toImage = false;
 };
 
@@ -241,8 +241,8 @@
     void populateVertices(float attWidth, float attHeight);
     void populateVertices(VkClearRect& clearRect, float attWidth, float attHeight);
 
-    std::vector<VkClearRect> _clearRects;
-    std::vector<simd::float4> _vertices;
+	MVKVectorInline<VkClearRect, 4> _clearRects;
+	MVKVectorInline<simd::float4, (4 * 6)> _vertices;
     simd::float4 _clearColors[kMVKClearAttachmentCount];
     VkClearValue _vkClearValues[kMVKClearAttachmentCount];
     MVKRPSKeyClearAtt _rpsKey;
@@ -278,7 +278,7 @@
     
     MVKImage* _image;
     VkImageLayout _imgLayout;
-    std::vector<VkImageSubresourceRange> _subresourceRanges;
+	MVKVectorInline<VkImageSubresourceRange, 4> _subresourceRanges;
 	MTLClearColor _mtlColorClearValue;
 	double _mtlDepthClearValue;
     uint32_t _mtlStencilClearValue;
@@ -330,7 +330,7 @@
     MVKBuffer* _dstBuffer;
     VkDeviceSize _dstOffset;
     VkDeviceSize _dataSize;
-    std::vector<uint8_t> _srcDataCache;
+    MVKVectorDefault<uint8_t> _srcDataCache;
 };
 
 
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
index 18f6dfe..ddeae21 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
@@ -23,8 +23,8 @@
 #include "MVKCommandEncoderState.h"
 #include "MVKMTLBufferAllocation.h"
 #include "MVKCmdPipeline.h"
+#include "MVKQueryPool.h"
 #include "MVKVector.h"
-#include <vector>
 #include <unordered_map>
 
 class MVKCommandPool;
@@ -240,7 +240,7 @@
 
 
 /*** Holds a collection of active queries for each query pool. */
-typedef std::unordered_map<MVKQueryPool*, std::vector<uint32_t>> MVKActivatedQueries;
+typedef std::unordered_map<MVKQueryPool*, MVKVectorInline<uint32_t, kMVKDefaultQueryCount>> MVKActivatedQueries;
 
 /** 
  * MVKCommandEncoder uses a visitor design pattern iterate the commands in a MVKCommandBuffer, 
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
index 40dfbd9..f43a495 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.mm
@@ -398,7 +398,7 @@
 // Clears the render area of the framebuffer attachments.
 void MVKCommandEncoder::clearRenderArea() {
 
-	vector<VkClearAttachment> clearAtts;
+	MVKVectorInline<VkClearAttachment, kMVKDefaultAttachmentCount> clearAtts;
 	getSubpass()->populateClearAttachments(clearAtts, _clearValues);
 
 	uint32_t clearAttCnt = (uint32_t)clearAtts.size();
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
index 901f457..9af8197 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandEncoderState.h
@@ -519,11 +519,11 @@
     void resetImpl() override;
     void markDirty() override;
 
-    MVKVectorDefault<MVKMTLBufferBinding> _bufferBindings;
-    MVKVectorDefault<MVKMTLTextureBinding> _textureBindings;
-    MVKVectorDefault<MVKMTLSamplerStateBinding> _samplerStateBindings;
-    MVKVectorDefault<uint32_t> _swizzleConstants;
-    MVKVectorDefault<uint32_t> _bufferSizes;
+    MVKVectorInline<MVKMTLBufferBinding, 4> _bufferBindings;
+    MVKVectorInline<MVKMTLTextureBinding, 4> _textureBindings;
+    MVKVectorInline<MVKMTLSamplerStateBinding, 4> _samplerStateBindings;
+    MVKVectorInline<uint32_t, 4> _swizzleConstants;
+    MVKVectorInline<uint32_t, 4> _bufferSizes;
     MVKMTLBufferBinding _swizzleBufferBinding;
     MVKMTLBufferBinding _bufferSizeBufferBinding;
 
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm b/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm
index 1c5d51e..668089f 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandPool.mm
@@ -123,6 +123,9 @@
 	_cmdDispatchIndirectPool.clear();
 	_cmdPushDescriptorSetPool.clear();
 	_cmdPushSetWithTemplatePool.clear();
+	_cmdDebugMarkerBeginPool.clear();
+	_cmdDebugMarkerEndPool.clear();
+	_cmdDebugMarkerInsertPool.clear();
 }
 
 
@@ -131,9 +134,9 @@
 MVKCommandPool::MVKCommandPool(MVKDevice* device,
 							   const VkCommandPoolCreateInfo* pCreateInfo) :
 	MVKVulkanAPIDeviceObject(device),
+	_queueFamilyIndex(pCreateInfo->queueFamilyIndex),
 	_commandBufferPool(device),
 	_commandEncodingPool(this),
-	_queueFamilyIndex(pCreateInfo->queueFamilyIndex),
 	_cmdPipelineBarrierPool(this),
 	_cmdBindPipelinePool(this),
 	_cmdBeginRenderPassPool(this),
@@ -143,13 +146,13 @@
 	_cmdBindDescriptorSetsPool(this),
 	_cmdSetViewportPool(this),
 	_cmdSetScissorPool(this),
-    _cmdSetLineWidthPool(this),
-    _cmdSetDepthBiasPool(this),
-    _cmdSetBlendConstantsPool(this),
-    _cmdSetDepthBoundsPool(this),
-    _cmdSetStencilCompareMaskPool(this),
-    _cmdSetStencilWriteMaskPool(this),
-    _cmdSetStencilReferencePool(this),
+	_cmdSetLineWidthPool(this),
+	_cmdSetDepthBiasPool(this),
+	_cmdSetBlendConstantsPool(this),
+	_cmdSetDepthBoundsPool(this),
+	_cmdSetStencilCompareMaskPool(this),
+	_cmdSetStencilWriteMaskPool(this),
+	_cmdSetStencilReferencePool(this),
 	_cmdBindVertexBuffersPool(this),
 	_cmdBindIndexBufferPool(this),
 	_cmdDrawPool(this),
@@ -158,26 +161,27 @@
 	_cmdDrawIndexedIndirectPool(this),
 	_cmdCopyImagePool(this),
 	_cmdBlitImagePool(this),
-    _cmdResolveImagePool(this),
-    _cmdFillBufferPool(this),
-    _cmdUpdateBufferPool(this),
+	_cmdResolveImagePool(this),
+	_cmdFillBufferPool(this),
+	_cmdUpdateBufferPool(this),
 	_cmdCopyBufferPool(this),
-    _cmdBufferImageCopyPool(this),
+	_cmdBufferImageCopyPool(this),
 	_cmdClearAttachmentsPool(this),
 	_cmdClearImagePool(this),
-    _cmdBeginQueryPool(this),
-    _cmdEndQueryPool(this),
+	_cmdBeginQueryPool(this),
+	_cmdEndQueryPool(this),
 	_cmdWriteTimestampPool(this),
-    _cmdResetQueryPoolPool(this),
-    _cmdCopyQueryPoolResultsPool(this),
+	_cmdResetQueryPoolPool(this),
+	_cmdCopyQueryPoolResultsPool(this),
 	_cmdPushConstantsPool(this),
-    _cmdDispatchPool(this),
-    _cmdDispatchIndirectPool(this),
-    _cmdPushDescriptorSetPool(this),
-    _cmdPushSetWithTemplatePool(this),
+	_cmdDispatchPool(this),
+	_cmdDispatchIndirectPool(this),
+	_cmdPushDescriptorSetPool(this),
+	_cmdPushSetWithTemplatePool(this),
 	_cmdDebugMarkerBeginPool(this),
 	_cmdDebugMarkerEndPool(this),
 	_cmdDebugMarkerInsertPool(this)
+// when extending be sure to add to trim() as well
 {}
 
 MVKCommandPool::~MVKCommandPool() {
diff --git a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
index eef16f6..c5ff171 100644
--- a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
+++ b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
@@ -22,7 +22,7 @@
 #include "MVKFoundation.h"
 #include "MVKObjectPool.h"
 #include "MVKDevice.h"
-#include <vector>
+#include "MVKVector.h"
 
 class MVKMTLBufferAllocationPool;
 
@@ -97,7 +97,7 @@
     NSUInteger _nextOffset;
     NSUInteger _allocationLength;
     NSUInteger _mtlBufferLength;
-    std::vector<id<MTLBuffer>> _mtlBuffers;
+	MVKVectorInline<id<MTLBuffer>, 64> _mtlBuffers;
     MVKDevice* _device;
 };
 
@@ -142,7 +142,7 @@
     ~MVKMTLBufferAllocator() override;
 
 protected:
-    std::vector<MVKMTLBufferAllocationPool*> _regionPools;
+	MVKVectorInline<MVKMTLBufferAllocationPool*, 32> _regionPools;
     NSUInteger _maxAllocationLength;
 	bool _makeThreadSafe;
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
index f5eb7b6..9b80795 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
@@ -24,7 +24,6 @@
 #include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
 #include <unordered_set>
 #include <unordered_map>
-#include <vector>
 
 class MVKDescriptorPool;
 class MVKDescriptorBinding;
@@ -118,7 +117,7 @@
 
 	MVKDescriptorSetLayout* _layout;
 	VkDescriptorSetLayoutBinding _info;
-	std::vector<MVKSampler*> _immutableSamplers;
+	MVKVectorInline<MVKSampler*, 16> _immutableSamplers;
 	MVKShaderResourceBinding _mtlResourceIndexOffsets;
 	bool _applyToStage[kMVKShaderStageMax];
 };
@@ -272,13 +271,13 @@
 
 	MVKDescriptorSet* _pDescSet;
 	MVKDescriptorSetLayoutBinding* _pBindingLayout;
-	std::vector<VkDescriptorImageInfo> _imageBindings;
-	std::vector<VkDescriptorBufferInfo> _bufferBindings;
-	std::vector<VkBufferView> _texelBufferBindings;
-	std::vector<id<MTLBuffer>> _mtlBuffers;
-	std::vector<NSUInteger> _mtlBufferOffsets;
-	std::vector<id<MTLTexture>> _mtlTextures;
-	std::vector<id<MTLSamplerState>> _mtlSamplers;
+	MVKVectorInline<VkDescriptorImageInfo, 1> _imageBindings;
+	MVKVectorInline<VkDescriptorBufferInfo, 1> _bufferBindings;
+	MVKVectorInline<VkBufferView, 1> _texelBufferBindings;
+	MVKVectorInline<id<MTLBuffer>, 1> _mtlBuffers;
+	MVKVectorInline<NSUInteger, 1> _mtlBufferOffsets;
+	MVKVectorInline<id<MTLTexture>, 1> _mtlTextures;
+	MVKVectorInline<id<MTLSamplerState>, 1> _mtlSamplers;
 	bool _hasDynamicSamplers;
 };
 
@@ -324,7 +323,7 @@
     MVKDescriptorBinding* getBinding(uint32_t binding);
 
 	MVKDescriptorSetLayout* _pLayout = nullptr;
-	std::vector<MVKDescriptorBinding> _bindings;
+	MVKVectorInline<MVKDescriptorBinding, 8> _bindings;
 };
 
 
@@ -408,7 +407,7 @@
 	void propogateDebugName() override {}
 
 	VkDescriptorUpdateTemplateTypeKHR _type;
-	std::vector<VkDescriptorUpdateTemplateEntryKHR> _entries;
+	MVKVectorInline<VkDescriptorUpdateTemplateEntryKHR, 4> _entries;
 };
 
 #pragma mark -
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
index e087ea1..3ce7590 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.h
@@ -22,9 +22,9 @@
 #include "MVKVulkanAPIObject.h"
 #include "MVKLayers.h"
 #include "MVKObjectPool.h"
+#include "MVKVector.h"
 #include "mvk_datatypes.hpp"
 #include "vk_mvk_moltenvk.h"
-#include <vector>
 #include <string>
 #include <mutex>
 
@@ -67,6 +67,10 @@
 const static uint32_t kMVKVertexContentBufferIndex = 0;
 
 // Parameters to define the sizing of inline collections
+const static uint32_t kMVKQueueFamilyCount = 4;
+const static uint32_t kMVKQueueCountPerQueueFamily = 1;		// Must be 1. See comments in MVKPhysicalDevice::getQueueFamilies()
+const static uint32_t kMVKMinSwapchainImageCount = 2;
+const static uint32_t kMVKMaxSwapchainImageCount = 3;
 const static uint32_t kMVKCachedViewportScissorCount = 16;
 const static uint32_t kMVKCachedColorAttachmentCount = 8;
 
@@ -328,7 +332,7 @@
 	void initMemoryProperties();
 	void initExtensions();
 	MVKExtensionList* getSupportedExtensions(const char* pLayerName = nullptr);
-	std::vector<MVKQueueFamily*>& getQueueFamilies();
+	MVKVector<MVKQueueFamily*>& getQueueFamilies();
 	void initPipelineCacheUUID();
 	MTLFeatureSet getHighestMTLFeatureSet();
 	uint64_t getSpirvCrossRevision();
@@ -343,7 +347,7 @@
 	VkPhysicalDeviceProperties _properties;
 	VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT _texelBuffAlignProperties;
 	VkPhysicalDeviceMemoryProperties _memoryProperties;
-	std::vector<MVKQueueFamily*> _queueFamilies;
+	MVKVectorInline<MVKQueueFamily*, kMVKQueueFamilyCount> _queueFamilies;
 	uint32_t _allMemoryTypes;
 	uint32_t _hostVisibleMemoryTypes;
 	uint32_t _hostCoherentMemoryTypes;
@@ -677,8 +681,8 @@
 	MVKPhysicalDevice* _physicalDevice;
     MVKCommandResourceFactory* _commandResourceFactory;
 	MTLCompileOptions* _mtlCompileOptions;
-	std::vector<std::vector<MVKQueue*>> _queuesByQueueFamilyIndex;
-	std::vector<MVKResource*> _resources;
+	MVKVectorInline<MVKVectorInline<MVKQueue*, kMVKQueueCountPerQueueFamily>, kMVKQueueFamilyCount> _queuesByQueueFamilyIndex;
+	MVKVectorInline<MVKResource*, 256> _resources;
 	std::mutex _rezLock;
     std::mutex _perfLock;
     id<MTLBuffer> _globalVisibilityResultMTLBuffer;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
index e9e481f..438674c 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDevice.mm
@@ -606,16 +606,16 @@
 // Metal does not distinguish functionality between queues, which would normally lead us
 // to create only only one general-purpose queue family. However, Vulkan associates command
 // buffers with a queue family, whereas Metal associates command buffers with a Metal queue.
-// In order to allow a Metal command buffer to be prefilled before is is formally submitted to
+// In order to allow a Metal command buffer to be prefilled before it is formally submitted to
 // a Vulkan queue, we need to enforce that each Vulkan queue family can have only one Metal queue.
 // In order to provide parallel queue operations, we therefore provide multiple queue families.
-vector<MVKQueueFamily*>& MVKPhysicalDevice::getQueueFamilies() {
+MVKVector<MVKQueueFamily*>& MVKPhysicalDevice::getQueueFamilies() {
 	if (_queueFamilies.empty()) {
 		VkQueueFamilyProperties qfProps;
 		bool specialize = _mvkInstance->getMoltenVKConfiguration()->specializedQueueFamilies;
 		uint32_t qfIdx = 0;
 
-		qfProps.queueCount = 1;		// Each queue family must have a single Metal queue (see above)
+		qfProps.queueCount = kMVKQueueCountPerQueueFamily;
 		qfProps.timestampValidBits = 64;
 		qfProps.minImageTransferGranularity = { 1, 1, 1};
 
@@ -634,6 +634,8 @@
 		// Dedicated transfer queue family...or another general-purpose queue family.
 		if (specialize) { qfProps.queueFlags = VK_QUEUE_TRANSFER_BIT; }
 		_queueFamilies.push_back(new MVKQueueFamily(this, qfIdx++, &qfProps));
+
+		MVKAssert(kMVKQueueFamilyCount >= _queueFamilies.size(), "Adjust value of kMVKQueueFamilyCount.");
 	}
 	return _queueFamilies;
 }
@@ -641,7 +643,7 @@
 VkResult MVKPhysicalDevice::getQueueFamilyProperties(uint32_t* pCount,
 													 VkQueueFamilyProperties* pQueueFamilyProperties) {
 
-	vector<MVKQueueFamily*> qFams = getQueueFamilies();
+	auto& qFams = getQueueFamilies();
 	uint32_t qfCnt = uint32_t(qFams.size());
 
 	// If properties aren't actually being requested yet, simply update the returned count
@@ -750,8 +752,8 @@
 	_metalFeatures.ioSurfaces = MVK_SUPPORT_IOSURFACE_BOOL;
 
 	// Metal supports 2 or 3 concurrent CAMetalLayer drawables.
-	_metalFeatures.minSwapchainImageCount = 2;
-	_metalFeatures.maxSwapchainImageCount = 3;
+	_metalFeatures.minSwapchainImageCount = kMVKMinSwapchainImageCount;
+	_metalFeatures.maxSwapchainImageCount = kMVKMaxSwapchainImageCount;
 
 #if MVK_IOS
 	_metalFeatures.mslVersionEnum = MTLLanguageVersion1_0;
@@ -2088,14 +2090,14 @@
 	mvkDevMem->destroy();
 }
 
-/** Adds the specified resource for tracking, and returns the added resource. */
+// Adds the specified resource for tracking, and returns the added resource.
 MVKResource* MVKDevice::addResource(MVKResource* rez) {
 	lock_guard<mutex> lock(_rezLock);
 	_resources.push_back(rez);
 	return rez;
 }
 
-/** Removes the specified resource for tracking and returns the removed resource. */
+// Removes the specified resource for tracking and returns the removed resource.
 MVKResource* MVKDevice::removeResource(MVKResource* rez) {
 	lock_guard<mutex> lock(_rezLock);
 	mvkRemoveFirstOccurance(_resources, rez);
@@ -2488,7 +2490,7 @@
 
 // Create the command queues
 void MVKDevice::initQueues(const VkDeviceCreateInfo* pCreateInfo) {
-	vector<MVKQueueFamily*> qFams = _physicalDevice->getQueueFamilies();
+	auto& qFams = _physicalDevice->getQueueFamilies();
 	uint32_t qrCnt = pCreateInfo->queueCreateInfoCount;
 	for (uint32_t qrIdx = 0; qrIdx < qrCnt; qrIdx++) {
 		const VkDeviceQueueCreateInfo* pQFInfo = &pCreateInfo->pQueueCreateInfos[qrIdx];
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
index c87b443..9d468ef 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDeviceMemory.h
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "MVKDevice.h"
-#include <vector>
+#include "MVKVector.h"
 #include <mutex>
 
 #import <Metal/Metal.h>
@@ -128,8 +128,8 @@
 	void freeHostMemory();
 	MVKResource* getDedicatedResource();
 
-	std::vector<MVKBuffer*> _buffers;
-	std::vector<MVKImage*> _images;
+	MVKVectorInline<MVKBuffer*, 4> _buffers;
+	MVKVectorInline<MVKImage*, 4> _images;
 	std::mutex _rezLock;
     VkDeviceSize _allocationSize = 0;
 	VkDeviceSize _mapOffset = 0;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h b/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h
index 9fd9ef3..e7a0852 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKFramebuffer.h
@@ -20,7 +20,7 @@
 
 #include "MVKDevice.h"
 #include "MVKImage.h"
-#include <vector>
+#include "MVKVector.h"
 
 
 #pragma mark MVKFramebuffer
@@ -56,6 +56,6 @@
 
 	VkExtent2D _extent;
 	uint32_t _layerCount;
-	std::vector<MVKImageView*> _attachments;
+	MVKVectorInline<MVKImageView*, 8> _attachments;
 };
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
index 0cbf0d0..68fdd23 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKImage.h
@@ -257,7 +257,7 @@
 						   VkPipelineStageFlags dstStageMask,
 						   VkImageMemoryBarrier* pImageMemoryBarrier);
 
-	std::vector<MVKImageSubresource> _subresources;
+	MVKVectorInline<MVKImageSubresource, 4> _subresources;
 	std::unordered_map<NSUInteger, id<MTLTexture>> _mtlTextureViews;
     VkExtent3D _extent;
     uint32_t _mipLevels;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
index 5771fe6..4bbef89 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.h
@@ -21,8 +21,8 @@
 #include "MVKEnvironment.h"
 #include "MVKLayers.h"
 #include "MVKVulkanAPIObject.h"
+#include "MVKVector.h"
 #include "vk_mvk_moltenvk.h"
-#include <vector>
 #include <unordered_map>
 #include <string>
 #include <mutex>
@@ -100,7 +100,7 @@
 	VkResult getPhysicalDeviceGroups(uint32_t* pCount, VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProps);
 
 	/** Returns the driver layer. */
-	MVKLayer* getDriverLayer() { return MVKLayerManager::globalManager()->getDriverLayer(); }
+	MVKLayer* getDriverLayer() { return getLayerManager()->getDriverLayer(); }
 
 	MVKSurface* createSurface(const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
 							  const VkAllocationCallbacks* pAllocator);
@@ -187,10 +187,10 @@
 
 	MVKConfiguration _mvkConfig;
 	VkApplicationInfo _appInfo;
-	std::vector<MVKPhysicalDevice*> _physicalDevices;
+	MVKVectorInline<MVKPhysicalDevice*, 4> _physicalDevices;
+	MVKVectorInline<MVKDebugReportCallback*, 4> _debugReportCallbacks;
+	MVKVectorInline<MVKDebugUtilsMessenger*, 4> _debugUtilMessengers;
 	std::unordered_map<std::string, MVKEntryPoint> _entryPoints;
-	std::vector<MVKDebugReportCallback*> _debugReportCallbacks;
-	std::vector<MVKDebugUtilsMessenger*> _debugUtilMessengers;
 	std::mutex _dcbLock;
 	bool _hasDebugReportCallbacks;
 	bool _hasDebugUtilsMessengers;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
index ce9fa40..0bb9bef 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKInstance.mm
@@ -666,7 +666,7 @@
 VkResult MVKInstance::verifyLayers(uint32_t count, const char* const* names) {
     VkResult result = VK_SUCCESS;
     for (uint32_t i = 0; i < count; i++) {
-        if ( !MVKLayerManager::globalManager()->getLayerNamed(names[i]) ) {
+        if ( !getLayerManager()->getLayerNamed(names[i]) ) {
             result = reportError(VK_ERROR_LAYER_NOT_PRESENT, "Vulkan layer %s is not supported.", names[i]);
         }
     }
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h
index 23bdb68..90d86f1 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.h
@@ -20,7 +20,6 @@
 
 #include "MVKDevice.h"
 #include "MVKVector.h"
-#include <vector>
 #include <mutex>
 #include <condition_variable>
 
@@ -29,7 +28,8 @@
 class MVKCommandEncoder;
 
 // The size of one query slot in bytes
-#define kMVKQuerySlotSizeInBytes      sizeof(uint64_t)
+#define kMVKQuerySlotSizeInBytes		sizeof(uint64_t)
+#define kMVKDefaultQueryCount			64
 
 
 #pragma mark -
@@ -57,7 +57,7 @@
     virtual void endQuery(uint32_t query, MVKCommandEncoder* cmdEncoder);
 
     /** Finishes the specified queries and marks them as available. */
-    virtual void finishQueries(std::vector<uint32_t>& queries);
+    virtual void finishQueries(MVKVector<uint32_t>& queries);
 
 	/** Resets the results and availability status of the specified queries. */
 	virtual void resetResults(uint32_t firstQuery, uint32_t queryCount, MVKCommandEncoder* cmdEncoder);
@@ -101,7 +101,7 @@
 	MVKQueryPool(MVKDevice* device,
 				 const VkQueryPoolCreateInfo* pCreateInfo,
 				 const uint32_t queryElementCount) : MVKVulkanAPIDeviceObject(device),
-                    _availability(pCreateInfo->queryCount),
+                    _availability(pCreateInfo->queryCount, Initial),
                     _queryElementCount(queryElementCount) {}
 
 protected:
@@ -127,12 +127,12 @@
 		Available           /**< Query is available to the host. */
 	};
 
-	std::vector<Status> _availability;
+	MVKVectorInline<Status, kMVKDefaultQueryCount> _availability;
+	MVKVectorInline<DeferredCopy, 4> _deferredCopies;
 	uint32_t _queryElementCount;
 	std::mutex _availabilityLock;
 	std::condition_variable _availabilityBlocker;
 	std::mutex _deferredCopiesLock;
-	MVKVectorInline<DeferredCopy, 2> _deferredCopies;
 };
 
 
@@ -143,7 +143,7 @@
 class MVKTimestampQueryPool : public MVKQueryPool {
 
 public:
-    void finishQueries(std::vector<uint32_t>& queries) override;
+    void finishQueries(MVKVector<uint32_t>& queries) override;
 
 
 #pragma mark Construction
@@ -156,7 +156,7 @@
 	id<MTLBuffer> getResultBuffer(MVKCommandEncoder* cmdEncoder, uint32_t firstQuery, uint32_t queryCount, NSUInteger& offset) override;
 	void encodeSetResultBuffer(MVKCommandEncoder* cmdEncoder, uint32_t firstQuery, uint32_t queryCount, uint32_t index) override;
 
-	std::vector<uint64_t> _timestamps;
+	MVKVectorInline<uint64_t, kMVKDefaultQueryCount> _timestamps;
 };
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm
index 0090244..b174d07 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueryPool.mm
@@ -47,7 +47,7 @@
 }
 
 // Mark queries as available
-void MVKQueryPool::finishQueries(vector<uint32_t>& queries) {
+void MVKQueryPool::finishQueries(MVKVector<uint32_t>& queries) {
     lock_guard<mutex> lock(_availabilityLock);
     for (uint32_t qry : queries) { _availability[qry] = Available; }
     _availabilityBlocker.notify_all();      // Predicate of each wait() call will check whether all required queries are available
@@ -184,7 +184,7 @@
 #pragma mark MVKTimestampQueryPool
 
 // Update timestamp values, then mark queries as available
-void MVKTimestampQueryPool::finishQueries(vector<uint32_t>& queries) {
+void MVKTimestampQueryPool::finishQueries(MVKVector<uint32_t>& queries) {
     uint64_t ts = mvkGetTimestamp();
     for (uint32_t qry : queries) { _timestamps[qry] = ts; }
 
@@ -215,7 +215,8 @@
 #pragma mark Construction
 
 MVKTimestampQueryPool::MVKTimestampQueryPool(MVKDevice* device,
-											 const VkQueryPoolCreateInfo* pCreateInfo) : MVKQueryPool(device, pCreateInfo, 1), _timestamps(pCreateInfo->queryCount) {
+											 const VkQueryPoolCreateInfo* pCreateInfo) :
+	MVKQueryPool(device, pCreateInfo, 1), _timestamps(pCreateInfo->queryCount, 0) {
 }
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
index 0cd2c53..d41bfee 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
@@ -23,7 +23,6 @@
 #include "MVKImage.h"
 #include "MVKSync.h"
 #include "MVKVector.h"
-#include <vector>
 #include <mutex>
 
 #import <Metal/Metal.h>
@@ -65,7 +64,7 @@
 	MVKPhysicalDevice* _physicalDevice;
     uint32_t _queueFamilyIndex;
 	VkQueueFamilyProperties _properties;
-	std::vector<id<MTLCommandQueue>> _mtlQueues;
+	MVKVectorInline<id<MTLCommandQueue>, kMVKQueueCountPerQueueFamily> _mtlQueues;
 	std::mutex _qLock;
 };
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
index a93dba6..70b6ea4 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.h
@@ -20,7 +20,6 @@
 
 #include "MVKDevice.h"
 #include "MVKVector.h"
-#include <vector>
 
 #import <Metal/Metal.h>
 
@@ -28,6 +27,10 @@
 class MVKFramebuffer;
 
 
+// Parameters to define the sizing of inline collections
+const static uint32_t kMVKDefaultAttachmentCount = 8;
+
+
 #pragma mark -
 #pragma mark MVKRenderSubpass
 
@@ -70,7 +73,7 @@
 	 * Populates the specified vector with the attachments that need to be cleared
 	 * when the render area is smaller than the full framebuffer size.
 	 */
-	void populateClearAttachments(std::vector<VkClearAttachment>& clearAtts,
+	void populateClearAttachments(MVKVector<VkClearAttachment>& clearAtts,
 								  MVKVector<VkClearValue>& clearValues);
 
 	/** Constructs an instance for the specified parent renderpass. */
@@ -85,10 +88,10 @@
 
 	MVKRenderPass* _renderPass;
 	uint32_t _subpassIndex;
-	std::vector<VkAttachmentReference> _inputAttachments;
-	std::vector<VkAttachmentReference> _colorAttachments;
-	std::vector<VkAttachmentReference> _resolveAttachments;
-	std::vector<uint32_t> _preserveAttachments;
+	MVKVectorInline<VkAttachmentReference, kMVKDefaultAttachmentCount> _inputAttachments;
+	MVKVectorInline<VkAttachmentReference, kMVKDefaultAttachmentCount> _colorAttachments;
+	MVKVectorInline<VkAttachmentReference, kMVKDefaultAttachmentCount> _resolveAttachments;
+	MVKVectorInline<uint32_t, kMVKDefaultAttachmentCount> _preserveAttachments;
 	VkAttachmentReference _depthStencilAttachment;
 	id<MTLTexture> _mtlDummyTex = nil;
 };
@@ -168,9 +171,9 @@
 
 	void propogateDebugName() override {}
 
-	std::vector<MVKRenderSubpass> _subpasses;
-	std::vector<MVKRenderPassAttachment> _attachments;
-	std::vector<VkSubpassDependency> _subpassDependencies;
+	MVKVectorInline<MVKRenderPassAttachment, kMVKDefaultAttachmentCount> _attachments;
+	MVKVectorInline<MVKRenderSubpass, 4> _subpasses;
+	MVKVectorInline<VkSubpassDependency, 4 * 2> _subpassDependencies;
 
 };
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
index 52609af..4ee7b1c 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKRenderPass.mm
@@ -165,7 +165,7 @@
 	}
 }
 
-void MVKRenderSubpass::populateClearAttachments(vector<VkClearAttachment>& clearAtts,
+void MVKRenderSubpass::populateClearAttachments(MVKVector<VkClearAttachment>& clearAtts,
 												MVKVector<VkClearValue>& clearValues) {
 	VkClearAttachment cAtt;
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
index d9a8f84..4ef1dfb 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKShaderModule.h
@@ -20,9 +20,9 @@
 
 #include "MVKDevice.h"
 #include "MVKSync.h"
+#include "MVKVector.h"
 #include <MoltenVKSPIRVToMSLConverter/SPIRVToMSLConverter.h>
 #include <MoltenVKGLSLToSPIRVConverter/GLSLToSPIRVConverter.h>
-#include <vector>
 #include <mutex>
 
 #import <Metal/Metal.h>
@@ -151,7 +151,7 @@
 	void merge(MVKShaderLibraryCache* other);
 
 	MVKVulkanAPIDeviceObject* _owner;
-	std::vector<std::pair<SPIRVToMSLConversionConfiguration, MVKShaderLibrary*>> _shaderLibraries;
+	MVKVectorInline<std::pair<SPIRVToMSLConversionConfiguration, MVKShaderLibrary*>, 4> _shaderLibraries;
 };
 
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
index 20e3dbe..802f2ad 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSwapchain.h
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "MVKDevice.h"
-#include <vector>
+#include "MVKVector.h"
 
 class MVKSwapchainImage;
 class MVKWatermark;
@@ -111,7 +111,7 @@
 
 	CAMetalLayer* _mtlLayer;
     MVKWatermark* _licenseWatermark;
-	std::vector<MVKSwapchainImage*> _surfaceImages;
+	MVKVectorInline<MVKSwapchainImage*, kMVKMaxSwapchainImageCount> _surfaceImages;
 	std::atomic<uint64_t> _currentAcquisitionID;
     CGSize _mtlLayerOrigDrawSize;
     MVKSwapchainPerformance _performanceStatistics;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKSync.h b/MoltenVK/MoltenVK/GPUObjects/MVKSync.h
index fa5f647..24ac84f 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKSync.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKSync.h
@@ -23,7 +23,6 @@
 #include <mutex>
 #include <condition_variable>
 #include <unordered_set>
-#include <vector>
 
 class MVKFenceSitter;
 
diff --git a/MoltenVK/MoltenVK/Layers/MVKLayers.h b/MoltenVK/MoltenVK/Layers/MVKLayers.h
index b93742a..e4bbc42 100644
--- a/MoltenVK/MoltenVK/Layers/MVKLayers.h
+++ b/MoltenVK/MoltenVK/Layers/MVKLayers.h
@@ -20,7 +20,7 @@
 
 #include "MVKBaseObject.h"
 #include "MVKExtensions.h"
-#include <vector>
+#include "MVKVector.h"
 
 
 #pragma mark MVKLayer
@@ -115,7 +115,7 @@
 	static MVKLayerManager* globalManager();
 
 protected:
-	std::vector<MVKLayer> _layers;
+	MVKVectorInline<MVKLayer, 1> _layers;
 
 };
 
diff --git a/MoltenVK/MoltenVK/Utility/MVKVector.h b/MoltenVK/MoltenVK/Utility/MVKVector.h
index 3746100..eac2b57 100755
--- a/MoltenVK/MoltenVK/Utility/MVKVector.h
+++ b/MoltenVK/MoltenVK/Utility/MVKVector.h
@@ -42,8 +42,7 @@
 // Like std::vector, MVKVector is guaranteed to use contiguous memory, so if the

 // preallocated number of elements are exceeded, all elements are then in heap.

 // MVKVector supports just the necessary members to be compatible with MoltenVK

-// If C++17 will be the default in the future, code can be simplified quite

-// a bit.

+// If C++17 will be the default in the future, code can be simplified quite a bit.

 //

 // Example:

 //

@@ -55,8 +54,7 @@
 //  vector.emplace_back( 4 );

 //

 // If you don't need any inline storage use

-//  MVKVectorDefault<int> vector; // this is essentially the same as using

-//                                // std::vector

+//  MVKVectorDefault<int> vector;   // this is essentially the same as using std::vector

 //

 // Passing MVKVectorInline to a function would require to use the same template

 // parameters that have been used for declaration. To avoid this MVKVectorInline

@@ -182,6 +180,7 @@
   virtual const Type * const  back() const                                   = 0;

   virtual       Type *       &back()                                         = 0;

   virtual const Type * const *data() const                                   = 0;

+  virtual       Type *       *data()                                         = 0;

 

   virtual size_t              size() const                                   = 0;

   virtual bool                empty() const                                  = 0;

@@ -670,7 +669,7 @@
   // this is the growth strategy -> adjust to your needs

   size_t vector_GetNextCapacity() const

   {

-    constexpr auto ELEMENTS_FOR_64_BYTES = 64 / sizeof( Type );

+    constexpr auto ELEMENTS_FOR_64_BYTES = 64 / sizeof( Type* );

     constexpr auto MINIMUM_CAPACITY = ELEMENTS_FOR_64_BYTES > 4 ? ELEMENTS_FOR_64_BYTES : 4;

     const auto current_capacity = capacity();

     return MINIMUM_CAPACITY + ( 3 * current_capacity ) / 2;

@@ -830,6 +829,7 @@
   const Type * const  back()                       const override { return alc.ptr[alc.num_elements_used - 1]; }

         Type *       &back()                             override { return alc.ptr[alc.num_elements_used - 1]; }

   const Type * const *data()                       const override { return &alc.ptr[0]; }

+        Type *       *data()                             override { return &alc.ptr[0]; }

 

   size_t   size()                                  const override { return alc.num_elements_used; }

   bool     empty()                                 const override { return alc.num_elements_used == 0; }

@@ -931,6 +931,21 @@
     }

   }

 

+  void erase( const iterator first, const iterator last )

+  {

+    if( first.is_valid() )

+    {

+      size_t last_pos = last.is_valid() ? last.get_position() : size();

+      size_t n = last_pos - first.get_position();

+      alc.num_elements_used -= n;

+

+      for( size_t i = first.get_position(), e = last_pos; i < alc.num_elements_used && e < alc.num_elements_used + n; ++i, ++e )

+      {

+        alc.ptr[i] = alc.ptr[e];

+      }

+    }

+  }

+

   // adds t before position it and automatically resizes vector if necessary

   void insert( const iterator it, const Type *t )

   {