Consolidate the various linkable objects into a MVKLinkableMixin template base class.

Update MoltenVK version number to 1.0.37.
diff --git a/Docs/Whats_New.md b/Docs/Whats_New.md
index 50c5b0b..15bcbe5 100644
--- a/Docs/Whats_New.md
+++ b/Docs/Whats_New.md
@@ -20,7 +20,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.
 
 
 MoltenVK 1.0.36
diff --git a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
index f5d029d..d67de99 100644
--- a/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
+++ b/MoltenVK/MoltenVK/API/vk_mvk_moltenvk.h
@@ -50,7 +50,7 @@
  */
 #define MVK_VERSION_MAJOR   1
 #define MVK_VERSION_MINOR   0
-#define MVK_VERSION_PATCH   36
+#define MVK_VERSION_PATCH   37
 
 #define MVK_MAKE_VERSION(major, minor, patch)    (((major) * 10000) + ((minor) * 100) + (patch))
 #define MVK_VERSION     MVK_MAKE_VERSION(MVK_VERSION_MAJOR, MVK_VERSION_MINOR, MVK_VERSION_PATCH)
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommand.h b/MoltenVK/MoltenVK/Commands/MVKCommand.h
index ce32b91..4d71165 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommand.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommand.h
@@ -33,7 +33,7 @@
 #pragma mark MVKCommand
 
 /** Abstract class that represents a Vulkan command. */
-class MVKCommand : public MVKConfigurableObject {
+class MVKCommand : public MVKConfigurableObject, public MVKLinkableMixin<MVKCommand> {
 
 public:
 
@@ -50,7 +50,7 @@
 	virtual void encode(MVKCommandEncoder* cmdEncoder) = 0;
 
 	/** 
-     * Returns this object back to the pool that created it. This will reset the value of _next member.
+     * Returns this object back to the pool that created it.
      *
      * This method is not thread-safe. Vulkan Command Pools are externally synchronized. 
      * For a particular MVKCommandTypePool instance, all calls to pool->aquireObject(), 
@@ -78,13 +78,6 @@
     /** Returns the underlying Metal device. */
     id<MTLDevice> getMTLDevice();
 
-	/**
-	 * Instances of this class can participate in a linked list or pool. When so participating,
-	 * this is a reference to the next instance in the list or pool. This value should only be
-	 * managed and set by the list or pool.
-	 */
-	MVKCommand* _next = nullptr;
-
 protected:
     MVKCommandTypePool<MVKCommand>* _pool;
 	MVKCommandBuffer* _commandBuffer = nullptr;
diff --git a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
index 2a6289a..18f6dfe 100644
--- a/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
+++ b/MoltenVK/MoltenVK/Commands/MVKCommandBuffer.h
@@ -50,8 +50,9 @@
 #pragma mark MVKCommandBuffer
 
 /** Represents a Vulkan command pool. */
-class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject, public MVKDeviceTrackingMixin {
-
+class MVKCommandBuffer : public MVKDispatchableVulkanAPIObject,
+						 public MVKDeviceTrackingMixin,
+						 public MVKLinkableMixin<MVKCommandBuffer> {
 public:
 
 	/** Returns the Vulkan type of this object. */
@@ -96,13 +97,6 @@
      */
     id<MTLBuffer> _initialVisibilityResultMTLBuffer;
 
-	/**
-	 * Instances of this class can participate in a linked list or pool. When so participating,
-	 * this is a reference to the next instance in the list or pool. This value should only be
-	 * managed and set by the list or pool.
-	 */
-	MVKCommandBuffer* _next;
-
 
 #pragma mark Constituent render pass management
     /** Preps metadata for recording render pass */
diff --git a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
index 822dac8..eef16f6 100644
--- a/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
+++ b/MoltenVK/MoltenVK/Commands/MVKMTLBufferAllocation.h
@@ -31,7 +31,7 @@
 #pragma mark MVKMTLBufferAllocation
 
 /** Defines a contiguous region of bytes within a MTLBuffer. */
-class MVKMTLBufferAllocation : public MVKBaseObject {
+class MVKMTLBufferAllocation : public MVKBaseObject, public MVKLinkableMixin<MVKMTLBufferAllocation> {
 
 public:
     id<MTLBuffer> _mtlBuffer;
@@ -50,7 +50,7 @@
     /** Returns the pool whence this object was created. */
     MVKMTLBufferAllocationPool* getPool() const { return _pool; }
 
-	/** Returns this object back to the pool that created it. This will reset the value of _next member. */
+	/** Returns this object back to the pool that created it. */
     void returnToPool();
 
 	/** Constructs this instance with the specified pool as its origin. */
@@ -59,13 +59,6 @@
                            NSUInteger offset,
                            NSUInteger length) : _pool(pool), _mtlBuffer(mtlBuffer), _offset(offset), _length(length) {}
 
-    /**
-	 * Instances of this class can participate in a linked list or pool. When so participating,
-	 * this is a reference to the next instance in the list or pool. This value should only be
-	 * managed and set by the list or pool.
-	 */
-	MVKMTLBufferAllocation* _next = nullptr;
-
 protected:
 	MVKMTLBufferAllocationPool* _pool;
 
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
index 6bd5ae8..f5eb7b6 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKDescriptorSet.h
@@ -287,7 +287,7 @@
 #pragma mark MVKDescriptorSet
 
 /** Represents a Vulkan descriptor set. */
-class MVKDescriptorSet : public MVKVulkanAPIDeviceObject {
+class MVKDescriptorSet : public MVKVulkanAPIDeviceObject, public MVKLinkableMixin<MVKDescriptorSet> {
 
 public:
 
@@ -313,13 +313,6 @@
 							VkDescriptorBufferInfo* pBufferInfo,
 							VkBufferView* pTexelBufferView);
 
-	/**
-	 * Instances of this class can participate in a linked list or pool. When so participating,
-	 * this is a reference to the next instance in the list or pool. This value should only be
-	 * managed and set by the list or pool.
-	 */
-	MVKDescriptorSet* _next;
-
 	MVKDescriptorSet(MVKDevice* device) : MVKVulkanAPIDeviceObject(device) {}
 
 protected:
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
index 7e326f6..0cd2c53 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.h
@@ -180,8 +180,6 @@
 	friend class MVKQueue;
 
 	MVKQueue* _queue;
-	MVKQueueSubmission* _prev;
-	MVKQueueSubmission* _next;
 	MVKVectorInline<MVKSemaphore*, 8> _waitSemaphores;
 	bool _isAwaitingSemaphores;
 	bool _trackPerformance;
diff --git a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
index 6a8647d..f0cc7f8 100644
--- a/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
+++ b/MoltenVK/MoltenVK/GPUObjects/MVKQueue.mm
@@ -202,8 +202,6 @@
 									   uint32_t waitSemaphoreCount,
 									   const VkSemaphore* pWaitSemaphores) {
 	_queue = queue;
-	_prev = nullptr;
-	_next = nullptr;
 	_trackPerformance = _queue->_device->_pMVKConfig->performanceTracking;
 
 	_isAwaitingSemaphores = waitSemaphoreCount > 0;
diff --git a/MoltenVK/MoltenVK/Utility/MVKObjectPool.h b/MoltenVK/MoltenVK/Utility/MVKObjectPool.h
index 732743e..ed7019f 100644
--- a/MoltenVK/MoltenVK/Utility/MVKObjectPool.h
+++ b/MoltenVK/MoltenVK/Utility/MVKObjectPool.h
@@ -23,14 +23,36 @@
 #include <mutex>
 
 
+/**
+ * Instances of sublcasses of this mixin can participate in a typed linked list or pool.
+ * A simple implementation of the CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
+ */
+template <class T>
+class MVKLinkableMixin {
+
+public:
+
+	/**
+	 * When participating in a linked list or pool, this is a reference to the next instance
+	 * in the list or pool. This value should only be managed and set by the list or pool.
+	 */
+	T* _next = nullptr;
+
+protected:
+	friend T;
+	MVKLinkableMixin() {};
+};
+
+
 #pragma mark -
 #pragma mark MVKObjectPool
 
 /**
  * Manages a pool of instances of a particular object type.
  *
- * The objects managed by this pool must have public member variable named "_next", 
- * of the same object type, which is used by this pool to create a linked list of objects.
+ * The objects managed by this pool should derive from MVKLinkableMixin, or otherwise
+ * support a public member variable named "_next", of the same object type, which is
+ * used by this pool to create a linked list of objects.
  *
  * When this pool is destroyed, any objects contained in the pool are also destroyed.
  *