layers: Add type safety to VK_OBJECT uses

Typedef VK_OBJECT as the more typesafe VulkanTypedHandle.  Use more
typesafe forms in various container insertions.  Disambiguate uniform
and initializer list usages, given the new constructors.

Add 64 bit specific assert to validate that kVulkanObjectType argument
matches the traits type.

Change-Id: I8661b68d778ae36da121c25fd80e5c44265893e0
diff --git a/scripts/helper_file_generator.py b/scripts/helper_file_generator.py
index 35ea403..7ea4e2a 100644
--- a/scripts/helper_file_generator.py
+++ b/scripts/helper_file_generator.py
@@ -664,7 +664,8 @@
     #
     # Object types header: create object enum type header file
     def GenerateObjectTypesHeader(self):
-        object_types_header = ''
+        object_types_header = '#include "cast_utils.h"\n'
+        object_types_header += '\n'
         object_types_header += '// Object Type enum for validation layer internal object handling\n'
         object_types_header += 'typedef enum VulkanObjectType {\n'
         object_types_header += '    kVulkanObjectTypeUnknown = 0,\n'
@@ -831,9 +832,23 @@
                 uint64_t handle;
                 VulkanObjectType type;
                 template <typename Handle>
-                VulkanTypedHandle(Handle handle_) :
-                    handle(reinterpret_cast<uint64_t>(handle_)),
-                    type(VkHandleInfo<Handle>::kVulkanObjectType) {}
+                VulkanTypedHandle(Handle handle_, VulkanObjectType type_) :
+                    handle(CastToUint64(handle_)),
+                    type(type_) {
+            #ifdef TYPESAFE_NONDISPATCHABLE_HANDLES
+                    // For 32 bit it's not always safe to check for traits <-> type
+                    // as all non-dispatchable handles have the same type-id and thus traits,
+                    // but on 64 bit we can validate the passed type matches the passed handle
+                    assert(type == VkHandleInfo<Handle>::kVulkanObjectType);
+            #endif // TYPESAFE_NONDISPATCHABLE_HANDLES
+                }
+                template <typename Handle>
+                Handle Cast() const {
+            #ifdef TYPESAFE_NONDISPATCHABLE_HANDLES
+                    assert(type == VkHandleInfo<Handle>::kVulkanObjectType);
+            #endif // TYPESAFE_NONDISPATCHABLE_HANDLES
+                    return CastFromUint64<Handle>(handle);
+                }
                 VulkanTypedHandle() :
                     handle(VK_NULL_HANDLE),
                     type(kVulkanObjectTypeUnknown) {}