text:
namespace Krust
{

VkImageCreateInfo CreateDepthImageInfo(const uint32_t presentQueueFamily, const VkFormat depthFormat, const uint32_t width, const uint32_t height)
{
  KRUST_ASSERT2(IsDepthFormat(depthFormat), "Format not usable for a depth buffer.");
  auto info = ImageCreateInfo();
  info.flags = 0,
    info.imageType = VK_IMAGE_TYPE_2D,
    info.format = depthFormat,
    info.extent.width = width,
    info.extent.height = height,
    info.extent.depth = 1,
    info.mipLevels = 1,
    info.arrayLayers = 1,
    info.samples = VK_SAMPLE_COUNT_1_BIT,
    info.tiling = VK_IMAGE_TILING_OPTIMAL,
    info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
    info.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
    info.queueFamilyIndexCount = 1,
    info.pQueueFamilyIndices = &presentQueueFamily,
    info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; // But I want to get into: VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

  return info;
}

VkImageView CreateDepthImageView(VkDevice device, VkImage image, const VkFormat format)
{
  auto viewInfo = ImageViewCreateInfo();
    viewInfo.flags = 0, //< No flags needed [Could set VK_IMAGE_VIEW_CREATE_READ_ONLY_DEPTH_BIT or VK_IMAGE_VIEW_CREATE_READ_ONLY_STENCIL_BIT for read-only depth buffer.]
    viewInfo.image = image,
    viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D,
    viewInfo.format = format,
    viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY,
    viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY,
    viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY,
    viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY,
    viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT,
    viewInfo.subresourceRange.baseMipLevel = 0,
    viewInfo.subresourceRange.levelCount = 1,
    viewInfo.subresourceRange.baseArrayLayer = 0,
    viewInfo.subresourceRange.layerCount = 1;

  VkImageView imageView;
  const VkResult result = vkCreateImageView(device, &viewInfo, Krust::Internal::sAllocator, &imageView);
  if(result != VK_SUCCESS)
  {
    KRUST_LOG_ERROR << "Failed to create image view for depth buffer. Error: " << result << endlog;
    imageView = 0;
  }
  return imageView;
}

VkResult ApplyImageBarrierBlocking(
  Krust::Device& device, VkImage image, VkQueue queue, Krust::CommandPool& pool,
  const VkImageMemoryBarrier& barrier)
{
  auto commandBuffer = CommandBuffer::New(pool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);

  auto commandBufferInheritanceInfo = CommandBufferInheritanceInfo();
    commandBufferInheritanceInfo.renderPass = nullptr,
    commandBufferInheritanceInfo.subpass = 0,
    commandBufferInheritanceInfo.framebuffer = nullptr,
    commandBufferInheritanceInfo.occlusionQueryEnable = VK_FALSE,
    commandBufferInheritanceInfo.queryFlags = 0,
    commandBufferInheritanceInfo.pipelineStatistics = 0;

  auto bufferBeginInfo = CommandBufferBeginInfo(
    VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
    &commandBufferInheritanceInfo);

    const VkResult beginBufferResult = vkBeginCommandBuffer(
      *commandBuffer,
      &bufferBeginInfo);

    if(VK_SUCCESS != beginBufferResult)
    {
      KRUST_LOG_ERROR << "Failed to begin command buffer. Error: " << beginBufferResult << Krust::endlog;
      return beginBufferResult;
    }

    vkCmdPipelineBarrier(
      *commandBuffer,
      VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
      VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
      0, // VkDependencyFlags
      0, nullptr,
      0, nullptr,
      1, &barrier);

    VK_CALL_RET_RES(vkEndCommandBuffer, *commandBuffer);

    // Submit the buffer and then wait for it to complete:

    constexpr VkPipelineStageFlags pipelineFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
    auto submitInfo = SubmitInfo(
      0, nullptr,
      &pipelineFlags,
      1, commandBuffer->GetVkCommandBufferAddress(),
      0, nullptr);

    // Execute command buffer on main queue:
    FencePtr fence {Fence::New(device, 0)};
    VK_CALL(vkQueueSubmit, queue, 1, &submitInfo, *fence);
    const VkResult fenceWaitResult = vkWaitForFences(device, 1, fence->GetVkFenceAddress(), true, 1000000000); // Wait one second.
    if(VK_SUCCESS != fenceWaitResult)
    {
      KRUST_LOG_ERROR << "Wait for queue submit of image memory barrier did not succeed: " << fenceWaitResult << Krust::endlog;
      return fenceWaitResult;
    }

  return VK_SUCCESS;
}

ConditionalValue<uint32_t>
FindFirstMemoryTypeWithProperties(const VkPhysicalDeviceMemoryProperties& memoryProperties, const uint32_t candidateTypeBitset, const VkMemoryPropertyFlags properties)
{
  const uint32_t count = std::min(uint32_t(VK_MAX_MEMORY_TYPES), memoryProperties.memoryTypeCount);
  for(uint32_t memoryType = 0; memoryType < count; ++memoryType)
  {
    // Check whether the memory type is in the bitset of allowable options:
    if(candidateTypeBitset & (1u << memoryType))
    {
      // Check whether all the requested properties are set for the memory type:
      const auto memory_flags = memoryProperties.memoryTypes[memoryType].propertyFlags;
      if((memory_flags & properties) == properties)
      {
        return ConditionalValue<uint32_t>(memoryType, true);
      }
    }
  }
  KRUST_LOG_WARN << "No suitable memory type found with the requested properties (" << properties << ") among the allowed types in the flag set (" << candidateTypeBitset << ")." << endlog;
  return ConditionalValue<uint32_t>(0, false);
}

ConditionalValue<uint32_t>
FindMemoryTypeMatchingProperties(const VkPhysicalDeviceMemoryProperties& memoryProperties, const uint32_t candidateTypeBitset, const VkMemoryPropertyFlags properties)
{
  const uint32_t count = std::min(uint32_t(VK_MAX_MEMORY_TYPES), memoryProperties.memoryTypeCount);
  for(uint32_t memoryType = 0; memoryType < count; ++memoryType)
  {
    // Check whether the memory type is in the bitset of allowable options:
    if(candidateTypeBitset & (1u << memoryType))
    {
      // Check whether all the requested properties are set for the memory type:
      if(memoryProperties.memoryTypes[memoryType].propertyFlags  == properties)
      {
        return ConditionalValue<uint32_t>(memoryType, true);
      }
    }
  }
  KRUST_LOG_WARN << "No suitable memory type found with the requested properties (" << properties << ") among the allowed types in the flag set (" << candidateTypeBitset << ")." << endlog;
  return ConditionalValue<uint32_t>(0, false);
}

ConditionalValue<uint32_t>
FindMemoryTypeWithAndWithout(
  const VkPhysicalDeviceMemoryProperties& memoryProperties,
  uint32_t candidateTypeBitset,
  VkMemoryPropertyFlags properties,
  VkMemoryPropertyFlags avoided_properties)
{
  const uint32_t count = std::min(uint32_t(VK_MAX_MEMORY_TYPES), memoryProperties.memoryTypeCount);
  for(uint32_t memoryType = 0; memoryType < count; ++memoryType)
  {
    // Check whether the memory type is in the bitset of allowable options:
    if(candidateTypeBitset & (1u << memoryType))
    {
      // Check whether all the requested properties are set for the memory type:
      if((memoryProperties.memoryTypes[memoryType].propertyFlags & properties) &&
         ((memoryProperties.memoryTypes[memoryType].propertyFlags & avoided_properties) == 0))
      {
        return ConditionalValue<uint32_t>(memoryType, true);
      }
    }
  }
  KRUST_LOG_WARN << "No suitable memory type found with the requested properties (" << properties << ") but without the avoided properties (" << avoided_properties << ") among the allowed types in the flag set (" << candidateTypeBitset << ")." << endlog;
  return ConditionalValue<uint32_t>(0, false);
}

bool IsDepthFormat(const VkFormat format)
{
  // Use this to find out the new number if the assert below fires:
  // KRUST_SHOW_UINT_AS_WARNING(VK_FORMAT_RANGE_SIZE);
  // Vulkan headers have started shipping withotu these useful extra enumernats:
  // KRUST_COMPILE_ASSERT(VK_FORMAT_RANGE_SIZE == 185, "Number of formats changed. Check if any are depth ones.");

  // Note, a depth format could be added while a non-depth one was removed and not
  // trigger the assert above.
  bool isDepth = false;
  if(format == VK_FORMAT_D16_UNORM ||
     format == VK_FORMAT_X8_D24_UNORM_PACK32 ||
     format == VK_FORMAT_D32_SFLOAT ||
     format == VK_FORMAT_D16_UNORM_S8_UINT ||
     format == VK_FORMAT_D24_UNORM_S8_UINT ||
     format == VK_FORMAT_D32_SFLOAT_S8_UINT)
  {
    isDepth = true;
  }

  return isDepth;
}

void LogResultError(const char* message, VkResult result)
{
  KRUST_LOG_ERROR << message << " Result: " << ResultToString(result) << "." << endlog;
}

const char* ResultToString(const VkResult result)
{
  const char *string = "<<Unknown Result Code>>";
  // Recreate with %s/\(VK_.*\) = .*,$/case \1: { string = "\1"; break; }/
  switch (result) {
    case VK_SUCCESS: { string = "VK_SUCCESS"; break; }
    case VK_NOT_READY: { string = "VK_NOT_READY"; break; }
    case VK_TIMEOUT: { string = "VK_TIMEOUT"; break; }
    case VK_EVENT_SET: { string = "VK_EVENT_SET"; break; }
    case VK_EVENT_RESET: { string = "VK_EVENT_RESET"; break; }
    case VK_INCOMPLETE: { string = "VK_INCOMPLETE"; break; }
    case VK_ERROR_OUT_OF_HOST_MEMORY: { string = "VK_ERROR_OUT_OF_HOST_MEMORY"; break; }
    case VK_ERROR_OUT_OF_DEVICE_MEMORY: { string = "VK_ERROR_OUT_OF_DEVICE_MEMORY"; break; }
    case VK_ERROR_INITIALIZATION_FAILED: { string = "VK_ERROR_INITIALIZATION_FAILED"; break; }
    case VK_ERROR_DEVICE_LOST: { string = "VK_ERROR_DEVICE_LOST"; break; }
    case VK_ERROR_MEMORY_MAP_FAILED: { string = "VK_ERROR_MEMORY_MAP_FAILED"; break; }
    case VK_ERROR_LAYER_NOT_PRESENT: { string = "VK_ERROR_LAYER_NOT_PRESENT"; break; }
    case VK_ERROR_EXTENSION_NOT_PRESENT: { string = "VK_ERROR_EXTENSION_NOT_PRESENT"; break; }
    case VK_ERROR_FEATURE_NOT_PRESENT: { string = "VK_ERROR_FEATURE_NOT_PRESENT"; break; }
    case VK_ERROR_INCOMPATIBLE_DRIVER: { string = "VK_ERROR_INCOMPATIBLE_DRIVER"; break; }
    case VK_ERROR_TOO_MANY_OBJECTS: { string = "VK_ERROR_TOO_MANY_OBJECTS"; break; }
    case VK_ERROR_FORMAT_NOT_SUPPORTED: { string = "VK_ERROR_FORMAT_NOT_SUPPORTED"; break; }
    case VK_ERROR_FRAGMENTED_POOL: { string = "VK_ERROR_FRAGMENTED_POOL"; break; }
    case VK_ERROR_UNKNOWN: { string = "VK_ERROR_UNKNOWN"; break; }
    case VK_ERROR_OUT_OF_POOL_MEMORY: { string = "VK_ERROR_OUT_OF_POOL_MEMORY"; break; }
    case VK_ERROR_INVALID_EXTERNAL_HANDLE: { string = "VK_ERROR_INVALID_EXTERNAL_HANDLE"; break; }
    case VK_ERROR_FRAGMENTATION: { string = "VK_ERROR_FRAGMENTATION"; break; }
    case VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: { string = "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; break; }
    case VK_ERROR_SURFACE_LOST_KHR: { string = "VK_ERROR_SURFACE_LOST_KHR"; break; }
    case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: { string = "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; break; }
    case VK_SUBOPTIMAL_KHR: { string = "VK_SUBOPTIMAL_KHR"; break; }
    case VK_ERROR_OUT_OF_DATE_KHR: { string = "VK_ERROR_OUT_OF_DATE_KHR"; break; }
    case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: { string = "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR"; break; }
    case VK_ERROR_VALIDATION_FAILED_EXT: { string = "VK_ERROR_VALIDATION_FAILED_EXT"; break; }
    case VK_ERROR_INVALID_SHADER_NV: { string = "VK_ERROR_INVALID_SHADER_NV"; break; }
    case VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT: { string = "VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT"; break; }
    case VK_ERROR_NOT_PERMITTED_EXT: { string = "VK_ERROR_NOT_PERMITTED_EXT"; break; }
    case VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT: { string = "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; break; }
    case VK_THREAD_IDLE_KHR: { string = "VK_THREAD_IDLE_KHR"; break; }
    case VK_THREAD_DONE_KHR: { string = "VK_THREAD_DONE_KHR"; break; }
    case VK_OPERATION_DEFERRED_KHR: { string = "VK_OPERATION_DEFERRED_KHR"; break; }
    case VK_OPERATION_NOT_DEFERRED_KHR: { string = "VK_OPERATION_NOT_DEFERRED_KHR"; break; }
    case VK_PIPELINE_COMPILE_REQUIRED_EXT: { string = "VK_PIPELINE_COMPILE_REQUIRED_EXT"; break; }

    // case VK_RESULT_RANGE_SIZE: { string = "VK_RESULT_RANGE_SIZE"; break; }
    case VK_RESULT_MAX_ENUM: { string = "VK_RESULT_MAX_ENUM"; break; }
  };

  return string;
}

int SortMetric(const VkPresentModeKHR mode, const bool tearingAllowed)
{
  /// @todo Revise code that chooses a present mode. Maybe force app to have a list from best to worst it knows about.
  // The modes are enumerated from best to worst, with the caveat that the first
  // will tear. Therefore we use their values as the metric but penalize the tearing
  // mode if tearing is not allowed.
  int sortKey = mode;
  if(!tearingAllowed && (mode == VK_PRESENT_MODE_IMMEDIATE_KHR))
  {
    sortKey += 128;
  }
  return sortKey;
}

const char* SurfaceTransformToString(const VkSurfaceTransformFlagsKHR transform)
{
  const char* text = "<<<UNKNOWN VK_SURFACE_TRANSFORM>>>";
  switch(transform)
  {
    case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR"; break; }
    case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR: { text = "VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR"; break; }
  };
  return text;
}

void BuildFences(
  Krust::Device& device,
  const VkFenceCreateFlags flags,
  const size_t numSwapChainImageViews,
  std::vector<FencePtr>& outSwapChainFences)
{
  outSwapChainFences.resize(numSwapChainImageViews);
  for(unsigned i = 0; i < numSwapChainImageViews; ++i)
  {
    outSwapChainFences[i] = Fence::New(device, flags);
  }
}

bool BuildFramebuffersForSwapChain(
  Krust::Device& device,
  const std::vector<VkImageView>& swapChainImageViews,
  const VkImageView depthBufferView,
  const uint32_t surfaceWidth, const uint32_t surfaceHeight,
  const VkFormat colorFormat,
  const VkFormat depthFormat,
  const VkSampleCountFlagBits colorSamples,
  std::vector<VkRenderPass>& outRenderPasses,
  std::vector<VkFramebuffer>& outSwapChainFramebuffers,
  std::vector<FencePtr>& outSwapChainFences)
{
  // Create RenderPass per swap chain image:
  VkAttachmentDescription attachments[2];
  attachments[0].flags = 0,
	  attachments[0].format = colorFormat,
	  attachments[0].samples = colorSamples,
	  attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
	  attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE,
	  attachments[0].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
	  attachments[0].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
	  attachments[0].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
	  attachments[0].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
	attachments[1].flags = 0,
		attachments[1].format = depthFormat,
		attachments[1].samples = colorSamples,
		attachments[1].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
		attachments[1].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
		attachments[1].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
		attachments[1].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
		attachments[1].initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
		attachments[1].finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

  VkAttachmentReference subpassColorAttachment;
    subpassColorAttachment.attachment = 0,
    subpassColorAttachment.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;

  VkAttachmentReference depthStencilAttachment;
    depthStencilAttachment.attachment = 1,
    depthStencilAttachment.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;

  VkSubpassDescription subpass;
  subpass.flags = 0,
    subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
    // Which of the two attachments of the RenderPass will be read at the start of
    // the Subpass. Since we do a clear at the start, we read zero of them.
    subpass.inputAttachmentCount = 0,
    subpass.pInputAttachments = nullptr,
    subpass.colorAttachmentCount = 1,
    subpass.pColorAttachments = &subpassColorAttachment,
    // Attachments to resolve multisample color into be we are not doing AA:
    subpass.pResolveAttachments = nullptr,
    subpass.pDepthStencilAttachment = &depthStencilAttachment,
    // Non-modified attachments which must be preserved:
    subpass.preserveAttachmentCount = 0,
    subpass.pPreserveAttachments = nullptr;

  auto renderPassInfo = RenderPassCreateInfo();
    renderPassInfo.flags = 0,
    renderPassInfo.attachmentCount = 2, // Depth and color.
    renderPassInfo.pAttachments = attachments,
    renderPassInfo.subpassCount = 1,
    renderPassInfo.pSubpasses = &subpass,
    // List of subpass pairs where the execution of flagged stages of the second
    // must wait for flagged stages of the first to complete,
    // but there is only one subpass so that is irrelevant:
    renderPassInfo.dependencyCount = 0,
    renderPassInfo.pDependencies = nullptr;

  KRUST_ASSERT1(outRenderPasses.size() == 0, "Double init of primary view renderpasses.");
  for(unsigned i = 0; i < swapChainImageViews.size(); ++i)
  {
    VkRenderPass renderPass;
    VK_CALL_RET(vkCreateRenderPass, device, &renderPassInfo, Krust::Internal::sAllocator, &renderPass);
    outRenderPasses.push_back(renderPass);
  }

  // Create a FrameBuffer object for each image in the swapchain that we are
  // going to be presenting to the screen:

  // Populate the second attachment as our depth buffer:
  VkImageView colorDepthViews[2];
  colorDepthViews[1] = depthBufferView;

  outSwapChainFramebuffers.resize(swapChainImageViews.size());
  auto framebufferInfo = FramebufferCreateInfo();
    framebufferInfo.flags = 0,
    framebufferInfo.renderPass = nullptr, // Init this inside loop below.
    framebufferInfo.attachmentCount = 2,
    framebufferInfo.pAttachments = colorDepthViews,
    framebufferInfo.width = surfaceWidth,
    framebufferInfo.height = surfaceHeight,
    framebufferInfo.layers = 1;

  for(unsigned i = 0; i < outSwapChainFramebuffers.size(); ++i)
  {
    framebufferInfo.renderPass = outRenderPasses[i];
    colorDepthViews[0] = swapChainImageViews[i]; // Reset color buffer, but share depth.
    VK_CALL_RET(vkCreateFramebuffer, device, &framebufferInfo, Krust::Internal::sAllocator, &outSwapChainFramebuffers[i]);
  }

  BuildFences(device, VK_FENCE_CREATE_SIGNALED_BIT, swapChainImageViews.size(), outSwapChainFences);

  return true;
}

const char* FormatToString(const VkFormat format)
{
  const char *string = "<<Unknown Format>>";
  // Recreate contents with: %s/\(VK_FORMAT.*\) = .*,$/case \1: { string = "\1"; break; }/
  switch (format) {
        case VK_FORMAT_UNDEFINED: { string = "VK_FORMAT_UNDEFINED"; break; }
    case VK_FORMAT_R4G4_UNORM_PACK8: { string = "VK_FORMAT_R4G4_UNORM_PACK8"; break; }
    case VK_FORMAT_R4G4B4A4_UNORM_PACK16: { string = "VK_FORMAT_R4G4B4A4_UNORM_PACK16"; break; }
    case VK_FORMAT_B4G4R4A4_UNORM_PACK16: { string = "VK_FORMAT_B4G4R4A4_UNORM_PACK16"; break; }
    case VK_FORMAT_R5G6B5_UNORM_PACK16: { string = "VK_FORMAT_R5G6B5_UNORM_PACK16"; break; }
    case VK_FORMAT_B5G6R5_UNORM_PACK16: { string = "VK_FORMAT_B5G6R5_UNORM_PACK16"; break; }
    case VK_FORMAT_R5G5B5A1_UNORM_PACK16: { string = "VK_FORMAT_R5G5B5A1_UNORM_PACK16"; break; }
    case VK_FORMAT_B5G5R5A1_UNORM_PACK16: { string = "VK_FORMAT_B5G5R5A1_UNORM_PACK16"; break; }
    case VK_FORMAT_A1R5G5B5_UNORM_PACK16: { string = "VK_FORMAT_A1R5G5B5_UNORM_PACK16"; break; }
    case VK_FORMAT_R8_UNORM: { string = "VK_FORMAT_R8_UNORM"; break; }
    case VK_FORMAT_R8_SNORM: { string = "VK_FORMAT_R8_SNORM"; break; }
    case VK_FORMAT_R8_USCALED: { string = "VK_FORMAT_R8_USCALED"; break; }
    case VK_FORMAT_R8_SSCALED: { string = "VK_FORMAT_R8_SSCALED"; break; }
    case VK_FORMAT_R8_UINT: { string = "VK_FORMAT_R8_UINT"; break; }
    case VK_FORMAT_R8_SINT: { string = "VK_FORMAT_R8_SINT"; break; }
    case VK_FORMAT_R8_SRGB: { string = "VK_FORMAT_R8_SRGB"; break; }
    case VK_FORMAT_R8G8_UNORM: { string = "VK_FORMAT_R8G8_UNORM"; break; }
    case VK_FORMAT_R8G8_SNORM: { string = "VK_FORMAT_R8G8_SNORM"; break; }
    case VK_FORMAT_R8G8_USCALED: { string = "VK_FORMAT_R8G8_USCALED"; break; }
    case VK_FORMAT_R8G8_SSCALED: { string = "VK_FORMAT_R8G8_SSCALED"; break; }
    case VK_FORMAT_R8G8_UINT: { string = "VK_FORMAT_R8G8_UINT"; break; }
    case VK_FORMAT_R8G8_SINT: { string = "VK_FORMAT_R8G8_SINT"; break; }
    case VK_FORMAT_R8G8_SRGB: { string = "VK_FORMAT_R8G8_SRGB"; break; }
    case VK_FORMAT_R8G8B8_UNORM: { string = "VK_FORMAT_R8G8B8_UNORM"; break; }
    case VK_FORMAT_R8G8B8_SNORM: { string = "VK_FORMAT_R8G8B8_SNORM"; break; }
    case VK_FORMAT_R8G8B8_USCALED: { string = "VK_FORMAT_R8G8B8_USCALED"; break; }
    case VK_FORMAT_R8G8B8_SSCALED: { string = "VK_FORMAT_R8G8B8_SSCALED"; break; }
    case VK_FORMAT_R8G8B8_UINT: { string = "VK_FORMAT_R8G8B8_UINT"; break; }
    case VK_FORMAT_R8G8B8_SINT: { string = "VK_FORMAT_R8G8B8_SINT"; break; }
    case VK_FORMAT_R8G8B8_SRGB: { string = "VK_FORMAT_R8G8B8_SRGB"; break; }
    case VK_FORMAT_B8G8R8_UNORM: { string = "VK_FORMAT_B8G8R8_UNORM"; break; }
    case VK_FORMAT_B8G8R8_SNORM: { string = "VK_FORMAT_B8G8R8_SNORM"; break; }
    case VK_FORMAT_B8G8R8_USCALED: { string = "VK_FORMAT_B8G8R8_USCALED"; break; }
    case VK_FORMAT_B8G8R8_SSCALED: { string = "VK_FORMAT_B8G8R8_SSCALED"; break; }
    case VK_FORMAT_B8G8R8_UINT: { string = "VK_FORMAT_B8G8R8_UINT"; break; }
    case VK_FORMAT_B8G8R8_SINT: { string = "VK_FORMAT_B8G8R8_SINT"; break; }
    case VK_FORMAT_B8G8R8_SRGB: { string = "VK_FORMAT_B8G8R8_SRGB"; break; }
    case VK_FORMAT_R8G8B8A8_UNORM: { string = "VK_FORMAT_R8G8B8A8_UNORM"; break; }
    case VK_FORMAT_R8G8B8A8_SNORM: { string = "VK_FORMAT_R8G8B8A8_SNORM"; break; }
    case VK_FORMAT_R8G8B8A8_USCALED: { string = "VK_FORMAT_R8G8B8A8_USCALED"; break; }
    case VK_FORMAT_R8G8B8A8_SSCALED: { string = "VK_FORMAT_R8G8B8A8_SSCALED"; break; }
    case VK_FORMAT_R8G8B8A8_UINT: { string = "VK_FORMAT_R8G8B8A8_UINT"; break; }
    case VK_FORMAT_R8G8B8A8_SINT: { string = "VK_FORMAT_R8G8B8A8_SINT"; break; }
    case VK_FORMAT_R8G8B8A8_SRGB: { string = "VK_FORMAT_R8G8B8A8_SRGB"; break; }
    case VK_FORMAT_B8G8R8A8_UNORM: { string = "VK_FORMAT_B8G8R8A8_UNORM"; break; }
    case VK_FORMAT_B8G8R8A8_SNORM: { string = "VK_FORMAT_B8G8R8A8_SNORM"; break; }
    case VK_FORMAT_B8G8R8A8_USCALED: { string = "VK_FORMAT_B8G8R8A8_USCALED"; break; }
    case VK_FORMAT_B8G8R8A8_SSCALED: { string = "VK_FORMAT_B8G8R8A8_SSCALED"; break; }
    case VK_FORMAT_B8G8R8A8_UINT: { string = "VK_FORMAT_B8G8R8A8_UINT"; break; }
    case VK_FORMAT_B8G8R8A8_SINT: { string = "VK_FORMAT_B8G8R8A8_SINT"; break; }
    case VK_FORMAT_B8G8R8A8_SRGB: { string = "VK_FORMAT_B8G8R8A8_SRGB"; break; }
    case VK_FORMAT_A8B8G8R8_UNORM_PACK32: { string = "VK_FORMAT_A8B8G8R8_UNORM_PACK32"; break; }
    case VK_FORMAT_A8B8G8R8_SNORM_PACK32: { string = "VK_FORMAT_A8B8G8R8_SNORM_PACK32"; break; }
    case VK_FORMAT_A8B8G8R8_USCALED_PACK32: { string = "VK_FORMAT_A8B8G8R8_USCALED_PACK32"; break; }
    case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: { string = "VK_FORMAT_A8B8G8R8_SSCALED_PACK32"; break; }
    case VK_FORMAT_A8B8G8R8_UINT_PACK32: { string = "VK_FORMAT_A8B8G8R8_UINT_PACK32"; break; }
    case VK_FORMAT_A8B8G8R8_SINT_PACK32: { string = "VK_FORMAT_A8B8G8R8_SINT_PACK32"; break; }
    case VK_FORMAT_A8B8G8R8_SRGB_PACK32: { string = "VK_FORMAT_A8B8G8R8_SRGB_PACK32"; break; }
    case VK_FORMAT_A2R10G10B10_UNORM_PACK32: { string = "VK_FORMAT_A2R10G10B10_UNORM_PACK32"; break; }
    case VK_FORMAT_A2R10G10B10_SNORM_PACK32: { string = "VK_FORMAT_A2R10G10B10_SNORM_PACK32"; break; }
    case VK_FORMAT_A2R10G10B10_USCALED_PACK32: { string = "VK_FORMAT_A2R10G10B10_USCALED_PACK32"; break; }
    case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: { string = "VK_FORMAT_A2R10G10B10_SSCALED_PACK32"; break; }
    case VK_FORMAT_A2R10G10B10_UINT_PACK32: { string = "VK_FORMAT_A2R10G10B10_UINT_PACK32"; break; }
    case VK_FORMAT_A2R10G10B10_SINT_PACK32: { string = "VK_FORMAT_A2R10G10B10_SINT_PACK32"; break; }
    case VK_FORMAT_A2B10G10R10_UNORM_PACK32: { string = "VK_FORMAT_A2B10G10R10_UNORM_PACK32"; break; }
    case VK_FORMAT_A2B10G10R10_SNORM_PACK32: { string = "VK_FORMAT_A2B10G10R10_SNORM_PACK32"; break; }
    case VK_FORMAT_A2B10G10R10_USCALED_PACK32: { string = "VK_FORMAT_A2B10G10R10_USCALED_PACK32"; break; }
    case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: { string = "VK_FORMAT_A2B10G10R10_SSCALED_PACK32"; break; }
    case VK_FORMAT_A2B10G10R10_UINT_PACK32: { string = "VK_FORMAT_A2B10G10R10_UINT_PACK32"; break; }
    case VK_FORMAT_A2B10G10R10_SINT_PACK32: { string = "VK_FORMAT_A2B10G10R10_SINT_PACK32"; break; }
    case VK_FORMAT_R16_UNORM: { string = "VK_FORMAT_R16_UNORM"; break; }
    case VK_FORMAT_R16_SNORM: { string = "VK_FORMAT_R16_SNORM"; break; }
    case VK_FORMAT_R16_USCALED: { string = "VK_FORMAT_R16_USCALED"; break; }
    case VK_FORMAT_R16_SSCALED: { string = "VK_FORMAT_R16_SSCALED"; break; }
    case VK_FORMAT_R16_UINT: { string = "VK_FORMAT_R16_UINT"; break; }
    case VK_FORMAT_R16_SINT: { string = "VK_FORMAT_R16_SINT"; break; }
    case VK_FORMAT_R16_SFLOAT: { string = "VK_FORMAT_R16_SFLOAT"; break; }
    case VK_FORMAT_R16G16_UNORM: { string = "VK_FORMAT_R16G16_UNORM"; break; }
    case VK_FORMAT_R16G16_SNORM: { string = "VK_FORMAT_R16G16_SNORM"; break; }
    case VK_FORMAT_R16G16_USCALED: { string = "VK_FORMAT_R16G16_USCALED"; break; }
    case VK_FORMAT_R16G16_SSCALED: { string = "VK_FORMAT_R16G16_SSCALED"; break; }
    case VK_FORMAT_R16G16_UINT: { string = "VK_FORMAT_R16G16_UINT"; break; }
    case VK_FORMAT_R16G16_SINT: { string = "VK_FORMAT_R16G16_SINT"; break; }
    case VK_FORMAT_R16G16_SFLOAT: { string = "VK_FORMAT_R16G16_SFLOAT"; break; }
    case VK_FORMAT_R16G16B16_UNORM: { string = "VK_FORMAT_R16G16B16_UNORM"; break; }
    case VK_FORMAT_R16G16B16_SNORM: { string = "VK_FORMAT_R16G16B16_SNORM"; break; }
    case VK_FORMAT_R16G16B16_USCALED: { string = "VK_FORMAT_R16G16B16_USCALED"; break; }
    case VK_FORMAT_R16G16B16_SSCALED: { string = "VK_FORMAT_R16G16B16_SSCALED"; break; }
    case VK_FORMAT_R16G16B16_UINT: { string = "VK_FORMAT_R16G16B16_UINT"; break; }
    case VK_FORMAT_R16G16B16_SINT: { string = "VK_FORMAT_R16G16B16_SINT"; break; }
    case VK_FORMAT_R16G16B16_SFLOAT: { string = "VK_FORMAT_R16G16B16_SFLOAT"; break; }
    case VK_FORMAT_R16G16B16A16_UNORM: { string = "VK_FORMAT_R16G16B16A16_UNORM"; break; }
    case VK_FORMAT_R16G16B16A16_SNORM: { string = "VK_FORMAT_R16G16B16A16_SNORM"; break; }
    case VK_FORMAT_R16G16B16A16_USCALED: { string = "VK_FORMAT_R16G16B16A16_USCALED"; break; }
    case VK_FORMAT_R16G16B16A16_SSCALED: { string = "VK_FORMAT_R16G16B16A16_SSCALED"; break; }
    case VK_FORMAT_R16G16B16A16_UINT: { string = "VK_FORMAT_R16G16B16A16_UINT"; break; }
    case VK_FORMAT_R16G16B16A16_SINT: { string = "VK_FORMAT_R16G16B16A16_SINT"; break; }
    case VK_FORMAT_R16G16B16A16_SFLOAT: { string = "VK_FORMAT_R16G16B16A16_SFLOAT"; break; }
    case VK_FORMAT_R32_UINT: { string = "VK_FORMAT_R32_UINT"; break; }
    case VK_FORMAT_R32_SINT: { string = "VK_FORMAT_R32_SINT"; break; }
    case VK_FORMAT_R32_SFLOAT: { string = "VK_FORMAT_R32_SFLOAT"; break; }
    case VK_FORMAT_R32G32_UINT: { string = "VK_FORMAT_R32G32_UINT"; break; }
    case VK_FORMAT_R32G32_SINT: { string = "VK_FORMAT_R32G32_SINT"; break; }
    case VK_FORMAT_R32G32_SFLOAT: { string = "VK_FORMAT_R32G32_SFLOAT"; break; }
    case VK_FORMAT_R32G32B32_UINT: { string = "VK_FORMAT_R32G32B32_UINT"; break; }
    case VK_FORMAT_R32G32B32_SINT: { string = "VK_FORMAT_R32G32B32_SINT"; break; }
    case VK_FORMAT_R32G32B32_SFLOAT: { string = "VK_FORMAT_R32G32B32_SFLOAT"; break; }
    case VK_FORMAT_R32G32B32A32_UINT: { string = "VK_FORMAT_R32G32B32A32_UINT"; break; }
    case VK_FORMAT_R32G32B32A32_SINT: { string = "VK_FORMAT_R32G32B32A32_SINT"; break; }
    case VK_FORMAT_R32G32B32A32_SFLOAT: { string = "VK_FORMAT_R32G32B32A32_SFLOAT"; break; }
    case VK_FORMAT_R64_UINT: { string = "VK_FORMAT_R64_UINT"; break; }
    case VK_FORMAT_R64_SINT: { string = "VK_FORMAT_R64_SINT"; break; }
    case VK_FORMAT_R64_SFLOAT: { string = "VK_FORMAT_R64_SFLOAT"; break; }
    case VK_FORMAT_R64G64_UINT: { string = "VK_FORMAT_R64G64_UINT"; break; }
    case VK_FORMAT_R64G64_SINT: { string = "VK_FORMAT_R64G64_SINT"; break; }
    case VK_FORMAT_R64G64_SFLOAT: { string = "VK_FORMAT_R64G64_SFLOAT"; break; }
    case VK_FORMAT_R64G64B64_UINT: { string = "VK_FORMAT_R64G64B64_UINT"; break; }
    case VK_FORMAT_R64G64B64_SINT: { string = "VK_FORMAT_R64G64B64_SINT"; break; }
    case VK_FORMAT_R64G64B64_SFLOAT: { string = "VK_FORMAT_R64G64B64_SFLOAT"; break; }
    case VK_FORMAT_R64G64B64A64_UINT: { string = "VK_FORMAT_R64G64B64A64_UINT"; break; }
    case VK_FORMAT_R64G64B64A64_SINT: { string = "VK_FORMAT_R64G64B64A64_SINT"; break; }
    case VK_FORMAT_R64G64B64A64_SFLOAT: { string = "VK_FORMAT_R64G64B64A64_SFLOAT"; break; }
    case VK_FORMAT_B10G11R11_UFLOAT_PACK32: { string = "VK_FORMAT_B10G11R11_UFLOAT_PACK32"; break; }
    case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: { string = "VK_FORMAT_E5B9G9R9_UFLOAT_PACK32"; break; }
    case VK_FORMAT_D16_UNORM: { string = "VK_FORMAT_D16_UNORM"; break; }
    case VK_FORMAT_X8_D24_UNORM_PACK32: { string = "VK_FORMAT_X8_D24_UNORM_PACK32"; break; }
    case VK_FORMAT_D32_SFLOAT: { string = "VK_FORMAT_D32_SFLOAT"; break; }
    case VK_FORMAT_S8_UINT: { string = "VK_FORMAT_S8_UINT"; break; }
    case VK_FORMAT_D16_UNORM_S8_UINT: { string = "VK_FORMAT_D16_UNORM_S8_UINT"; break; }
    case VK_FORMAT_D24_UNORM_S8_UINT: { string = "VK_FORMAT_D24_UNORM_S8_UINT"; break; }
    case VK_FORMAT_D32_SFLOAT_S8_UINT: { string = "VK_FORMAT_D32_SFLOAT_S8_UINT"; break; }
    case VK_FORMAT_BC1_RGB_UNORM_BLOCK: { string = "VK_FORMAT_BC1_RGB_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC1_RGB_SRGB_BLOCK: { string = "VK_FORMAT_BC1_RGB_SRGB_BLOCK"; break; }
    case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: { string = "VK_FORMAT_BC1_RGBA_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: { string = "VK_FORMAT_BC1_RGBA_SRGB_BLOCK"; break; }
    case VK_FORMAT_BC2_UNORM_BLOCK: { string = "VK_FORMAT_BC2_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC2_SRGB_BLOCK: { string = "VK_FORMAT_BC2_SRGB_BLOCK"; break; }
    case VK_FORMAT_BC3_UNORM_BLOCK: { string = "VK_FORMAT_BC3_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC3_SRGB_BLOCK: { string = "VK_FORMAT_BC3_SRGB_BLOCK"; break; }
    case VK_FORMAT_BC4_UNORM_BLOCK: { string = "VK_FORMAT_BC4_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC4_SNORM_BLOCK: { string = "VK_FORMAT_BC4_SNORM_BLOCK"; break; }
    case VK_FORMAT_BC5_UNORM_BLOCK: { string = "VK_FORMAT_BC5_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC5_SNORM_BLOCK: { string = "VK_FORMAT_BC5_SNORM_BLOCK"; break; }
    case VK_FORMAT_BC6H_UFLOAT_BLOCK: { string = "VK_FORMAT_BC6H_UFLOAT_BLOCK"; break; }
    case VK_FORMAT_BC6H_SFLOAT_BLOCK: { string = "VK_FORMAT_BC6H_SFLOAT_BLOCK"; break; }
    case VK_FORMAT_BC7_UNORM_BLOCK: { string = "VK_FORMAT_BC7_UNORM_BLOCK"; break; }
    case VK_FORMAT_BC7_SRGB_BLOCK: { string = "VK_FORMAT_BC7_SRGB_BLOCK"; break; }
    case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: { string = "VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK"; break; }
    case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: { string = "VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK"; break; }
    case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: { string = "VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK"; break; }
    case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: { string = "VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK"; break; }
    case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: { string = "VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK"; break; }
    case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: { string = "VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK"; break; }
    case VK_FORMAT_EAC_R11_UNORM_BLOCK: { string = "VK_FORMAT_EAC_R11_UNORM_BLOCK"; break; }
    case VK_FORMAT_EAC_R11_SNORM_BLOCK: { string = "VK_FORMAT_EAC_R11_SNORM_BLOCK"; break; }
    case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: { string = "VK_FORMAT_EAC_R11G11_UNORM_BLOCK"; break; }
    case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: { string = "VK_FORMAT_EAC_R11G11_SNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_4x4_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_4x4_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_5x4_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_5x4_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_5x5_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_5x5_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_6x5_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_6x5_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_6x6_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_6x6_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_8x5_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_8x5_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_8x6_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_8x6_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_8x8_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_8x8_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_10x5_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_10x5_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_10x6_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_10x6_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_10x8_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_10x8_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_10x10_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_10x10_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_12x10_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_12x10_SRGB_BLOCK"; break; }
    case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: { string = "VK_FORMAT_ASTC_12x12_UNORM_BLOCK"; break; }
    case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: { string = "VK_FORMAT_ASTC_12x12_SRGB_BLOCK"; break; }
    case VK_FORMAT_G8B8G8R8_422_UNORM: { string = "VK_FORMAT_G8B8G8R8_422_UNORM"; break; }
    case VK_FORMAT_B8G8R8G8_422_UNORM: { string = "VK_FORMAT_B8G8R8G8_422_UNORM"; break; }
    case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: { string = "VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM"; break; }
    case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: { string = "VK_FORMAT_G8_B8R8_2PLANE_420_UNORM"; break; }
    case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: { string = "VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM"; break; }
    case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: { string = "VK_FORMAT_G8_B8R8_2PLANE_422_UNORM"; break; }
    case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: { string = "VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM"; break; }
    case VK_FORMAT_R10X6_UNORM_PACK16: { string = "VK_FORMAT_R10X6_UNORM_PACK16"; break; }
    case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: { string = "VK_FORMAT_R10X6G10X6_UNORM_2PACK16"; break; }
    case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: { string = "VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16"; break; }
    case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: { string = "VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16"; break; }
    case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: { string = "VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16"; break; }
    case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: { string = "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16"; break; }
    case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: { string = "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16"; break; }
    case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: { string = "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16"; break; }
    case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: { string = "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16"; break; }
    case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: { string = "VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16"; break; }
    case VK_FORMAT_R12X4_UNORM_PACK16: { string = "VK_FORMAT_R12X4_UNORM_PACK16"; break; }
    case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: { string = "VK_FORMAT_R12X4G12X4_UNORM_2PACK16"; break; }
    case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: { string = "VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16"; break; }
    case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: { string = "VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16"; break; }
    case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: { string = "VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16"; break; }
    case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: { string = "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16"; break; }
    case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: { string = "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16"; break; }
    case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: { string = "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16"; break; }
    case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: { string = "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16"; break; }
    case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: { string = "VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16"; break; }
    case VK_FORMAT_G16B16G16R16_422_UNORM: { string = "VK_FORMAT_G16B16G16R16_422_UNORM"; break; }
    case VK_FORMAT_B16G16R16G16_422_UNORM: { string = "VK_FORMAT_B16G16R16G16_422_UNORM"; break; }
    case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: { string = "VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM"; break; }
    case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: { string = "VK_FORMAT_G16_B16R16_2PLANE_420_UNORM"; break; }
    case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: { string = "VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM"; break; }
    case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: { string = "VK_FORMAT_G16_B16R16_2PLANE_422_UNORM"; break; }
    case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: { string = "VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM"; break; }
    case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: { string = "VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: { string = "VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: { string = "VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: { string = "VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: { string = "VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: { string = "VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: { string = "VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG"; break; }
    case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: { string = "VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG"; break; }
    case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_6x5_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_6x6_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_8x5_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_8x6_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_8x8_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_10x5_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_10x6_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_10x8_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_10x10_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_12x10_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT: { string = "VK_FORMAT_ASTC_12x12_SFLOAT_BLOCK_EXT"; break; }
    case VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: { string = "VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT"; break; }
    case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT: { string = "VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT"; break; }
    case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT: { string = "VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT"; break; }
    case VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: { string = "VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT"; break; }
    case VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT: { string = "VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT"; break; }
    case VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT: { string = "VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT"; break; }

    // Specials (not actually formats):
    //case VK_FORMAT_RANGE_SIZE: { string = "VK_FORMAT_RANGE_SIZE"; break; }
    case VK_FORMAT_MAX_ENUM: {string = "VK_FORMAT_MAX_ENUM"; break; };
  };
  return string;
}

const char* KHRColorspaceToString(const VkColorSpaceKHR space)
{
  // KRUST_ASSERT2(space <= VK_COLOR_SPACE_END_RANGE_KHR, "Out of range color space.");
  const char* string = "<<unkown colorspace>>";
  // recreate cases below with: %s/\(VK_.*\) = .*,$/case \1: { string = "\1"; break; }/
  switch (space) {
    case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR: { string = "VK_COLOR_SPACE_SRGB_NONLINEAR_KHR"; break; }
    case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT: { string = "VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT"; break; }
    case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT: { string = "VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT"; break; }
    case VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT: { string = "VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT"; break; }
    case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT: { string = "VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT"; break; }
    case VK_COLOR_SPACE_BT709_LINEAR_EXT: { string = "VK_COLOR_SPACE_BT709_LINEAR_EXT"; break; }
    case VK_COLOR_SPACE_BT709_NONLINEAR_EXT: { string = "VK_COLOR_SPACE_BT709_NONLINEAR_EXT"; break; }
    case VK_COLOR_SPACE_BT2020_LINEAR_EXT: { string = "VK_COLOR_SPACE_BT2020_LINEAR_EXT"; break; }
    case VK_COLOR_SPACE_HDR10_ST2084_EXT: { string = "VK_COLOR_SPACE_HDR10_ST2084_EXT"; break; }
    case VK_COLOR_SPACE_DOLBYVISION_EXT: { string = "VK_COLOR_SPACE_DOLBYVISION_EXT"; break; }
    case VK_COLOR_SPACE_HDR10_HLG_EXT: { string = "VK_COLOR_SPACE_HDR10_HLG_EXT"; break; }
    case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT: { string = "VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT"; break; }
    case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT: { string = "VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT"; break; }
    case VK_COLOR_SPACE_PASS_THROUGH_EXT: { string = "VK_COLOR_SPACE_PASS_THROUGH_EXT"; break; }
    case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT: { string = "VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT"; break; }
    case VK_COLOR_SPACE_DISPLAY_NATIVE_AMD: { string = "VK_COLOR_SPACE_DISPLAY_NATIVE_AMD"; break; }

    // case VK_COLOR_SPACE_RANGE_SIZE_KHR: {string = "<<invalid: VK_COLORSPACE_RANGE_SIZE>>"; break; };
    case VK_COLOR_SPACE_MAX_ENUM_KHR: {string = "<<invalid: VK_COLORSPACE_MAX_ENUM>>"; break; };
  }
  return string;
}

PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char *const name) {
  KRUST_ASSERT1(name, "Must pass a name to look up.");
  const PFN_vkVoidFunction address = vkGetInstanceProcAddr(instance, name);
  if (!address) {
    KRUST_LOG_ERROR << "Failed to get the address of instance proc: " << name << endlog;
  }
  return address;
}

PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char *const name) {
  KRUST_ASSERT1(name, "Must pass a name to look up.");
  const PFN_vkVoidFunction address = vkGetDeviceProcAddr(device, name);
  if (!address) {
    KRUST_LOG_ERROR << "Failed to get the address of device proc: " << name << endlog;
  }
  return address;
}

bool FindExtension(const std::vector<VkExtensionProperties> &extensions, const char *const extension) {
  KRUST_ASSERT1(extension, "Name of extension to look up is missing.");
  for (auto potential : extensions) {
    if (strcmp(extension, potential.extensionName) == 0) {
      return true;
    }
  }
  KRUST_LOG_WARN << "Failed to find extension \"" << extension << "\"." << endlog;
  return false;
}

bool FindLayer(const std::vector<VkLayerProperties> &layers, const char *const layer) {
  KRUST_ASSERT1(layer, "Name of extension to look up is missing.");
  for (auto potential : layers) {
    if (strcmp(layer, potential.layerName) == 0) {
      return true;
    }
  }
  KRUST_LOG_WARN << "Failed to find layer \"" << layer << "\"." << endlog;
  return false;
}

const char *MessageFlagsToLevel(const VkFlags flags)
{
  const char* level = "UNKNOWN";
  switch (flags)
  {
  case VK_DEBUG_REPORT_INFORMATION_BIT_EXT: { level = "INFO"; break; }
  case VK_DEBUG_REPORT_WARNING_BIT_EXT: { level = "WARN"; break; }
  case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT: { level = "PERF_WARN"; break; }
  case VK_DEBUG_REPORT_ERROR_BIT_EXT: { level = "ERROR"; break; }
  case VK_DEBUG_REPORT_DEBUG_BIT_EXT: { level = "DEBUG"; break; }
  }
  return level;
}

std::vector<VkExtensionProperties>
EnumerateDeviceExtensionProperties(VkPhysicalDevice &gpu,
  const char *const name) {
  uint32_t count = 0;
  std::vector<VkExtensionProperties> properties;
  VkResult result = vkEnumerateDeviceExtensionProperties(gpu, name, &count, 0);
  if (result == VK_SUCCESS) {
    properties.resize(count);
    result = vkEnumerateDeviceExtensionProperties(gpu, name, &count, &properties[0]);
    if (result != VK_SUCCESS) {
      properties.clear();
      KRUST_LOG_ERROR << "Error getting physical device extensions: " << ResultToString(result) << endlog;
    }
  }
  return properties;
}

std::vector<VkLayerProperties> EnumerateDeviceLayerProperties(
  const VkPhysicalDevice &gpu) {
  uint32_t layerCount = 0;
  std::vector<VkLayerProperties> layerProperties;
  VkResult result = vkEnumerateDeviceLayerProperties(gpu, &layerCount, 0);
  if (result == VK_SUCCESS) {
    layerProperties.resize(layerCount);
    result = vkEnumerateDeviceLayerProperties(gpu, &layerCount, &layerProperties[0]);
    if (result != VK_SUCCESS) {
      layerProperties.resize(0);
    }
  }
  if (result != VK_SUCCESS) {
    KRUST_LOG_ERROR << "Failed to get GPU layer properties. Error: " << ResultToString(result) << endlog;
  }
  return layerProperties;
}

std::vector<VkQueueFamilyProperties> GetPhysicalDeviceQueueFamilyProperties(const VkPhysicalDevice gpu) {
  uint32_t count = 0;
  std::vector<VkQueueFamilyProperties> properties;

  vkGetPhysicalDeviceQueueFamilyProperties(gpu, &count, 0);
  properties.resize(count);
  vkGetPhysicalDeviceQueueFamilyProperties(gpu, &count, &properties[0]);

  return properties;
}

std::vector<VkExtensionProperties> GetGlobalExtensionProperties(const char *const name) {
  VkResult result;
  uint32_t extensionCount = 0;
  std::vector<VkExtensionProperties> extensionProperties;

  // We make the call once to get the size of the array to return and then again to
  // actually populate an array:

  result = vkEnumerateInstanceExtensionProperties(name, &extensionCount, 0);
  if (result) {
    KRUST_LOG_ERROR << ": vkGetGlobalExtensionProperties returned " << ResultToString(result) << ".\n";
  }
  else {
    extensionProperties.resize(extensionCount);
    result = vkEnumerateInstanceExtensionProperties(name, &extensionCount, &extensionProperties[0]);
    KRUST_ASSERT1(extensionCount <= extensionProperties.size(), "Extension count changed.");
    if (result) {
      extensionProperties.clear();
      KRUST_LOG_ERROR << ": vkGetGlobalExtensionProperties returned " << ResultToString(result) << ".\n";
    }
  }
  return extensionProperties;
}

std::vector<VkLayerProperties> EnumerateInstanceLayerProperties() {
  VkResult result;
  uint32_t layerCount = 0;
  std::vector<VkLayerProperties> layerProperties;

  // We make the call once to get the size of the array to return and then again to
  // actually populate an array:

  result = vkEnumerateInstanceLayerProperties(&layerCount, 0);
  if (result) {
    KRUST_LOG_ERROR << ": vkGetGlobalLayerProperties returned " << ResultToString(result) << ".\n";
  }
  else {
    layerProperties.resize(layerCount);
    result = vkEnumerateInstanceLayerProperties(&layerCount, &layerProperties[0]);
    KRUST_ASSERT1(layerCount <= layerProperties.size(), "Layer count changed");
    if (result) {
      layerProperties.clear();
      KRUST_LOG_ERROR << ": vkGetGlobalLayerProperties returned " << ResultToString(result) << ".\n";
    }
  }
  return layerProperties;
}

std::vector<VkPhysicalDevice> EnumeratePhysicalDevices(
  const VkInstance &instance) {
  uint32_t physicalDeviceCount;
  std::vector<VkPhysicalDevice> physicalDevices;

  // Query for the number of GPUs:
  VkResult gpuResult = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, 0);

  if (gpuResult == VK_SUCCESS) {
    // Go ahead and get the list of GPUs:
    physicalDevices.resize(physicalDeviceCount);
    gpuResult = vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, &physicalDevices[0]);

    if (gpuResult != VK_SUCCESS) {
      physicalDevices.resize(0);
    }
  }

  if (gpuResult != VK_SUCCESS) {
    KRUST_LOG_ERROR << "vkEnumeratePhysicalDevices() returned " << ResultToString(gpuResult) << ".\n";
  }

  return physicalDevices;
}

ScopedImageOwner::ScopedImageOwner(VkDevice dev, VkImage img) : device(dev), image(img)
{
  KRUST_ASSERT2(dev || !img, "Need a device so the destroy will work later.");
}

ScopedImageOwner::~ScopedImageOwner()
{
  if(image)
  {
    KRUST_ASSERT2(device, "No device so can't destroy.");
    vkDestroyImage(device, image, Krust::Internal::sAllocator);
  }
}

ScopedDeviceMemoryOwner::ScopedDeviceMemoryOwner(VkDevice dev,
                                                 VkDeviceMemory mem) :
  device(dev), memory(mem)
{
  KRUST_ASSERT2(dev || !mem, "Need a device so the free will work later.");
}

ScopedDeviceMemoryOwner::~ScopedDeviceMemoryOwner()
{
  if(memory)
  {
    KRUST_ASSERT2(device, "No device so can't free.");
    vkFreeMemory(device, memory, Krust::Internal::sAllocator);
  }
}

ShaderBuffer loadSpirV(const char* const filename)
{
  ShaderBuffer spirv;
  if(std::ifstream is{filename, std::ios::binary | std::ios::ate}) {
    auto size = is.tellg();
    spirv.resize(size / sizeof(ShaderBuffer::value_type));
    is.seekg(0);
    is.read((char*)&spirv[0], size);
  } else {
    KRUST_LOG_ERROR << "Failed to open shader file \"" << filename << "\"." << Krust::endlog;
  }
  return spirv;
}

}


text:
import "es6-shim";
import * as util from "../util";
import TransisObject from "../object";

describe('type', function() {
  it("returns the string 'null' when passed `null`", function() {
    expect(util.type(null)).toBe('null');
  });

  it("returns the string 'undefined' when passed `undefined`", function() {
    expect(util.type(undefined)).toBe('undefined');
    expect(util.type(void 0)).toBe('undefined');
  });

  it("returns the string 'array' when passed an Array instance", function() {
    expect(util.type([])).toBe('array');
    expect(util.type([1,2,3])).toBe('array');
  });

  it("returns the string 'arguments' when passed an Arguments instance", function() {
    var args = (function() { return arguments; }());
    expect(util.type(args)).toBe('arguments');
  });

  it("returns the string 'function' when passed a Function instance", function() {
    expect(util.type(function() {})).toBe('function');
    expect(util.type(Object)).toBe('function');
  });

  it("returns the string 'string' when passed a string", function() {
    expect(util.type('')).toBe('string');
    expect(util.type('foobar')).toBe('string');
  });

  it("returns the string 'number' when passed a number", function() {
    expect(util.type(0)).toBe('number');
    expect(util.type(1.234)).toBe('number');
    expect(util.type(NaN)).toBe('number');
    expect(util.type(1/0)).toBe('number');
  });

  it("returns the string 'boolean' when passed `true` or `false`", function() {
    expect(util.type(true)).toBe('boolean');
    expect(util.type(false)).toBe('boolean');
  });

  it("returns the string 'date' when passed a Date instance", function() {
    expect(util.type(new Date())).toBe('date');
  });

  it("returns the string 'regexp' when passed a RegExp instance", function() {
    expect(util.type(/foo/)).toBe('regexp');
    expect(util.type(new RegExp())).toBe('regexp');
  });

  it("should return the string 'object' when passed an Object instance", function() {
    expect(util.type({})).toBe('object');
    expect(util.type({foo: 1})).toBe('object');
  });
});

describe('eq', function() {
  describe('given a Transis.Object as the first argument', function() {
    it('invokes `eq` on the first argument', function() {
      var a = new TransisObject, b = new TransisObject;

      spyOn(a, 'eq');
      util.eq(a, b);
      expect(a.eq).toHaveBeenCalledWith(b);
    });
  });

  it('returns `true` for identical objects', function() {
    var a = [1,2], o = {foo: 1}, d = new Date(2012, 0, 29), r = /x/i;
    expect(util.eq(null, null)).toBe(true);
    expect(util.eq(undefined, undefined)).toBe(true);
    expect(util.eq(true, true)).toBe(true);
    expect(util.eq(false, false)).toBe(true);
    expect(util.eq(1, 1)).toBe(true);
    expect(util.eq('foo', 'foo')).toBe(true);
    expect(util.eq(r, r)).toBe(true);
    expect(util.eq(d, d)).toBe(true);
    expect(util.eq(a, a)).toBe(true);
    expect(util.eq(o, o)).toBe(true);
  });

  it('returns `false` when given `null` and `undefined`', function() {
    expect(util.eq(null, undefined)).toBe(false);
    expect(util.eq(undefined, null)).toBe(false);
  });

  it('returns `true` for string primitives and their corresponding wrapper objects', function() {
    expect(util.eq('foo', 'foo')).toBe(true);
    expect(util.eq('foo', new String('foo'))).toBe(true);
    expect(util.eq(new String('foo'), 'foo')).toBe(true);
    expect(util.eq(new String('foo'), new String('foo'))).toBe(true);
  });

  it('returns `false` for string primitives with different values', function() {
    expect(util.eq('foo', 'bar')).toBe(false);
    expect(util.eq('foo', 'Foo')).toBe(false);
  });

  it('returns `false` for string objects with different values', function() {
    expect(util.eq(new String('foo'), new String('Foo'))).toBe(false);
  });

  it('returns `true` when given `0` and `-0`', function() {
    expect(util.eq(0, -0)).toBe(true);
    expect(util.eq(-0, 0)).toBe(true);
  });

  it('returns `true` for number primitives and their corresponding wrapper objects', function() {
    expect(util.eq(21, 21)).toBe(true);
    expect(util.eq(new Number(21), new Number(21))).toBe(true);
    expect(util.eq(21, new Number(21))).toBe(true);
    expect(util.eq(new Number(21), 21)).toBe(true);
  });

  it('returns `false` for number objects with different values', function() {
    expect(util.eq(new Number(21), new Number(-21))).toBe(false);
    expect(util.eq(new Number(21), 22)).toBe(false);
    expect(util.eq(23, new Number(22))).toBe(false);
    expect(util.eq(23, 23.1)).toBe(false);
  });

  it('returns `false` when both objects are `NaN`', function() {
    expect(util.eq(NaN, NaN)).toBe(false);
  });

  it('returns `false` when `NaN` is compared with any other number value', function() {
    expect(util.eq(NaN, 1)).toBe(false);
    expect(util.eq(1, NaN)).toBe(false);
    expect(util.eq(new Number(1), NaN)).toBe(false);
    expect(util.eq(NaN, new Number(2))).toBe(false);
    expect(util.eq(NaN, Infinity)).toBe(false);
    expect(util.eq(Infinity, NaN)).toBe(false);
  });

  it('returns `true` for boolean primitives and their corresponding wrapper objects', function() {
    expect(util.eq(true, true)).toBe(true);
    expect(util.eq(false, false)).toBe(true);
    expect(util.eq(true, new Boolean(true))).toBe(true);
    expect(util.eq(new Boolean(true), true)).toBe(true);
    expect(util.eq(new Boolean(true), new Boolean(true))).toBe(true);
    expect(util.eq(false, new Boolean(false))).toBe(true);
    expect(util.eq(new Boolean(false), false)).toBe(true);
    expect(util.eq(new Boolean(false), new Boolean(false))).toBe(true);
    expect(util.eq(new Boolean(), new Boolean())).toBe(true);
    expect(util.eq(new Boolean(false), new Boolean())).toBe(true);
    expect(util.eq(new Boolean(), new Boolean(false))).toBe(true);
  });

  it('returns `false` for boolean objects with different primitive objects', function() {
    expect(util.eq(true, false)).toBe(false);
    expect(util.eq(false, true)).toBe(false);
    expect(util.eq(new Boolean(false), new Boolean(true))).toBe(false);
    expect(util.eq(new Boolean(true), new Boolean(false))).toBe(false);
    expect(util.eq(false, new Boolean(true))).toBe(false);
    expect(util.eq(new Boolean(true), false)).toBe(false);
    expect(util.eq(new Boolean(true), new Boolean())).toBe(false);
  });

  it('returns `true` for date objects containing identical times and `false` otherwise', function() {
    expect(util.eq(new Date(2012, 0, 30), new Date(2012, 0, 30))).toBe(true);
    expect(util.eq(new Date(2012, 0, 30, 8, 17, 1, 1), new Date(2012, 0, 30, 8, 17, 1, 1))).toBe(true);
    expect(util.eq(new Date(2012, 1, 2), new Date(2012, 1, 3))).toBe(false);
    expect(util.eq(new Date(2012, 1, 2, 6, 36, 0, 0), new Date(2012, 1, 2, 6, 36, 0, 1))).toBe(false);
  });

  it('returns `true` when given identical function references and `false` otherwise', function() {
    var f = function() {};

    expect(util.eq(f, f)).toBe(true);
    expect(util.eq(f, function() {})).toBe(false);
  });

  it('returns `true` for regular expressions with equal patterns and flags', function() {
    expect(util.eq(/^a*/gi, /^a*/gi)).toBe(true);
    expect(util.eq(/^a*/ig, /^a*/gi)).toBe(true);
    expect(util.eq(new RegExp('^a*', 'igm'), new RegExp('^a*', 'igm'))).toBe(true);
    expect(util.eq(new RegExp('^a*', 'igm'), new RegExp('^a*', 'mig'))).toBe(true);
    expect(util.eq(/^a*/gim, new RegExp('^a*', 'mig'))).toBe(true);
  });

  it('returns `false` for regular expressions where the patterns differ', function() {
    expect(util.eq(/^a*/, /a*/)).toBe(false);
    expect(util.eq(/^a*/ig, /a*/ig)).toBe(false);
    expect(util.eq(new RegExp('^a*'), new RegExp('a*'))).toBe(false);
  });

  it('returns `false` for regular expressions where the flags differ', function() {
    expect(util.eq(/^a*/, /^a*/i)).toBe(false);
    expect(util.eq(new RegExp('^a*', 'i'), new RegExp('a*', 'g'))).toBe(false);
  });

  describe('with native arrays', function() {
    it('returns `false` if any corresponding elements are not equal', function() {
      expect(util.eq([], [1])).toBe(false);
      expect(util.eq([2], [1])).toBe(false);
      expect(util.eq([1, 2], [1])).toBe(false);
      expect(util.eq([1, 2], [2, 1])).toBe(false);
      expect(util.eq([/x/], [/x/i])).toBe(false);
    });

    it('returns `true` if all corresponding elements are equal', function() {
      expect(util.eq([], [])).toBe(true);
      expect(util.eq([1], [1])).toBe(true);
      expect(util.eq([1, 'two', /3*/g], [1, 'two', /3*/g])).toBe(true);
    });

    it('handles recursive arrays', function() {
      var a1 = [1], a2 = [1], back, forth, x;

      a1.push(a1);
      a2.push(a2);
      expect(util.eq(a1, a2)).toBe(true);

      a1.push(a1);
      a2.push(a1);
      expect(util.eq(a1, a2)).toBe(true);

      a2.push('foo');
      expect(util.eq(a1, a2)).toBe(false);

      a1 = [];
      a1.push(a1);

      expect(util.eq(a1, [a1])).toBe(true);
      expect(util.eq(a1, [[a1]])).toBe(true);
      expect(util.eq([a1], a1)).toBe(true);
      expect(util.eq([[a1]], a1)).toBe(true);

      back = [];
      forth = [back];
      back.push(forth);
      expect(util.eq(back, a1)).toBe(true);

      x = [];
      x.push(x, x);
      expect(util.eq(x, a1)).toBe(false);
      expect(util.eq(x, [a1, a1])).toBe(false);
      expect(util.eq(x, [x, a1])).toBe(false);
      expect(util.eq([x, a1], [a1, x])).toBe(false);
      expect(util.eq(x, [x, x])).toBe(true);
      expect(util.eq(x, [[x, x], [x, x]])).toBe(true);
    });

    it('handles multi-demensional arrays', function() {
      expect(util.eq([[]], [[]])).toBe(true);
      expect(util.eq([1, [2, 3]], [1, [2, 3]])).toBe(true);
      expect(util.eq([1, [2, 3]], [1, 2, [3]])).toBe(false);
    });

    it('ignores non-numeric properties', function() {
      var a1 = [1, 2, 3], a2 = [1, 2, 3];

      a1.foo = 'bar';
      expect(util.eq(a1, a2)).toBe(true);
    });
  });

  describe('with plain objects', function() {
    it('returns `false` when the number of keys differ between the two objects', function() {
      expect(util.eq({}, {foo: 1})).toBe(false);
      expect(util.eq({foo: 1, bar: 2}, {foo: 1})).toBe(false);
    });

    it('returns `false` when there are different keys', function() {
      expect(util.eq({foo: 1}, {food: 1})).toBe(false);
    });

    it('returns `false` when there are different values for the same keys', function() {
      expect(util.eq({foo: 1}, {foo: 2})).toBe(false);
      expect(util.eq({foo: 1, bar: 2}, {foo: 2, bar: 3})).toBe(false);
    });

    it('returns `true` when each key/value pair is equal', function() {
      expect(util.eq({}, {})).toBe(true);
      expect(util.eq({foo: 1}, {foo: 1})).toBe(true);
      expect(util.eq({foo: 1, bar: 2}, {foo: 1, bar: 2})).toBe(true);
      expect(util.eq({bar: 2, foo: 1}, {foo: 1, bar: 2})).toBe(true);
    });

    it('handles nested objects', function() {
      expect(util.eq({a: {b: 'c'}}, {a: {b: 'c'}})).toBe(true);
      expect(util.eq({a: {b: 'c'}}, {a: {b: 'd'}})).toBe(false);

      expect(util.eq({ a: { b: [ { stuff: true }, 2, 3 ] }, foo: /y/ },
                      { foo: /y/, a: { b: [ { stuff: true }, 2, 3 ] } })).toBe(true);

      expect(util.eq({ a: { b: [ { stuff: true }, 2, 3 ] }, foo: /y/ },
                      { foo: /y/, a: { b: [ { stuff: false }, 2, 3 ] } })).toBe(false);
    });

    it('handles recursive objects', function() {
      var o = {};
      o.a = o;

      expect(util.eq(o, o.a)).toBe(true);
    });

    it('handles complex recursive objects', function() {
      var a = {}, b = {}, c = {};

      a.self  = a;
      a.other = b;
      b.self  = b;
      b.other = a;
      expect(util.eq(a, b)).toBe(true);

      c.other = c;
      c.self  = c;
      expect(util.eq(c, a)).toBe(true);

      a.delta = a;
      c.delta = a;
      expect(util.eq(c, a)).toBe(false);

      c.delta = 42;
      expect(util.eq(c, a)).toBe(false);

      a.delta = 42;
      expect(util.eq(c, a)).toBe(false);

      b.delta = 42;
      expect(util.eq(c, a)).toBe(true);
    });

    it('handles complex recursive objects and arrays', function() {
      var x = [], y = [], z = [], a, b, c;

      a = {foo: x, bar: 42};
      b = {foo: y, bar: 42};
      c = {foo: z, bar: 42};

      x.push(a);
      y.push(c);
      z.push(b);

      expect(util.eq(b, c)).toBe(true);
      expect(util.eq(y, z)).toBe(true);
      expect(util.eq(a, b)).toBe(true);

      expect(util.eq(x, y)).toBe(true);
      y.push(x);
      expect(util.eq(y, z)).toBe(false);
      z.push(x);
      expect(util.eq(y, z)).toBe(true);

      a.foo = a.bar;
      a.bar = a.foo;
      expect(util.eq(a, b)).toBe(false);
      b.bar = b.foo;
      expect(util.eq(b, c)).toBe(false);
    });
  });
});

describe('camelize', function() {
  it('camelizes the given string', function() {
    expect(util.camelize('foo_bar')).toBe('fooBar');
    expect(util.camelize('foo_bar_baz')).toBe('fooBarBaz');
    expect(util.camelize('foo_Bar_Baz')).toBe('fooBarBaz');
    expect(util.camelize('foobar')).toBe('foobar');
    expect(util.camelize('Foobar')).toBe('Foobar');
    expect(util.camelize('Foo_bar')).toBe('FooBar');
  });

  it('handles null and undefined values', function() {
    expect(util.camelize(null)).toBeNull();
    expect(util.camelize(undefined)).toBeUndefined();
  });

  it('handles empty strings', function() {
    expect(util.camelize('')).toBe('');
  });
});

describe('underscore', function() {
  it('underscores the given string', function() {
    expect(util.underscore('FooBar')).toBe('foo_bar');
    expect(util.underscore('fooBar')).toBe('foo_bar');
    expect(util.underscore('fooBarBaz')).toBe('foo_bar_baz');
    expect(util.underscore('fooBar_Baz')).toBe('foo_bar_baz');
    expect(util.underscore('Foo')).toBe('foo');
  });

  it('handles null and undefined values', function() {
    expect(util.underscore(null)).toBeNull();
    expect(util.underscore(undefined)).toBeUndefined();
  });

  it('handles empty strings', function() {
    expect(util.underscore('')).toBe('');
  });
});

describe('capitalize', function() {
  it('capitalizes the given string', function() {
    expect(util.capitalize('foo')).toBe('Foo');
    expect(util.capitalize('fooBar')).toBe('FooBar');
    expect(util.capitalize('FOO')).toBe('FOO');
    expect(util.capitalize('Foo')).toBe('Foo');
  });

  it('handles null and undefined values', function() {
    expect(util.capitalize(null)).toBeNull();
    expect(util.capitalize(undefined)).toBeUndefined();
  });

  it('handles empty strings', function() {
    expect(util.capitalize('')).toBe('');
  });
});

describe('getPath', function() {
  it('returns the value at each path relative to the given object', function() {
    var x = {foo: 1, bar: {baz: 2}};

    expect(util.getPath(x, 'foo')).toBe(1);
    expect(util.getPath(x, 'bar')).toBe(x.bar);
    expect(util.getPath(x, 'bar.baz')).toBe(2);
  });

  it('returns undefined when a segment of the path does not exist', function() {
    var a = {b: {}};
    expect(util.getPath(a, 'b.c.d.e')).toBeUndefined();
  });

  it('returns undefined when the given object is null or undefined', function() {
    expect(util.getPath(null, 'b.c.d.e')).toBeUndefined();
    expect(util.getPath(undefined, 'b.c.d.e')).toBeUndefined();
  });

  describe('with an array in the path', function() {
    beforeEach(function() {
      this.foo = {bars: [{x: 2}, {x: 4}, {x: 6}]};
    });

    describe('when the property exists on the array', function() {
      it('returns the property from the array', function() {
        expect(util.getPath(this.foo, 'bars.length')).toBe(3);
      });
    });

    describe('when the property does not exist on the array', function() {
      it('returns an array containing the values extracted from each item in the array', function() {
        expect(util.getPath(this.foo, 'bars.x')).toEqual([2, 4, 6]);
      });
    });

    describe('with multiple arrays in the path', function() {
      it('flattens the array', function() {
        var o = {
          foos: [
            {bars: [{x: 1}, {x: 5}]},
            {bars: [{x: 9}, {x: 3}, {x: 7}]},
            {bars: []},
            {bars: [{x: 2}]}
          ]
        };

        expect(util.getPath(o, 'foos.bars.x')).toEqual([1,5,9,3,7,2]);
      });

      it('strips null and undefined values', function() {
        var o = {
          foos: [
            {x: {bars: [{y: 9}, {y: 3}]}},
            {x: null},
            {},
            {x: {bars: [{y: 1}, {y: 4}]}},
          ]
        };

        expect(util.getPath(o, 'foos.x.bars.y')).toEqual([9,3,1,4]);
      });
    });
  });
});

redpajama_set_name: RedPajamaGithub


text:
using System;
using System.Collections.Generic;
using SJP.Schematic.Core;

namespace SJP.Schematic.Migrations.Comparers
{
    public class DatabaseSynonymComparer : IEqualityComparer<IDatabaseSynonym>
    {
        public bool Equals(IDatabaseSynonym x, IDatabaseSynonym y)
        {
            if (x is null && y is null)
                return true;
            if (x is null || y is null)
                return false;

            return x.Name == y.Name
                && x.Target == y.Target;
        }

        public int GetHashCode(IDatabaseSynonym obj)
        {
            if (obj == null)
                throw new ArgumentNullException(nameof(obj));

            return HashCode.Combine(
                obj.Name,
                obj.Target
            );
        }
    }
}


text:
from patternfinder import PatternFinder

__all__ = [
    "PatternFinder"
]


text:
package com.obtuse.ui.layout.linear;

import com.obtuse.ui.MyActionListener;
import com.obtuse.ui.layout.ConstraintTuple;
import com.obtuse.ui.layout.LinearOrientation;
import com.obtuse.util.BasicProgramConfigInfo;
import com.obtuse.util.Logger;
import com.obtuse.util.ObtuseUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Hashtable;
import java.util.TreeMap;

/**
 A linear layout manager that supports component and container constraints.
 */

public class LinearLayoutManager3 implements LayoutManager2 {

    public interface Constraint {

        String getName();

        boolean isEnabled();

    }

    public static final String TRACK_PARENTS_BREADTH_CONSTRAINT_TITLE = "track parent's breadth";

    public static final LinearLayoutManager3.SimpleConstraint TRACK_PARENTS_BREADTH_CONSTRAINT = new LinearLayoutManager3.SimpleConstraint(
            LinearLayoutManager3.TRACK_PARENTS_BREADTH_CONSTRAINT_TITLE,
            true
    );

    public static class SimpleConstraint implements Constraint {

        private final String _name;

        private final boolean _enabled;

        public SimpleConstraint( @SuppressWarnings("SameParameterValue") final @NotNull String name, final boolean enabled ) {

            super();

            _name = name;

            _enabled = enabled;

        }

        public String getName() {

            return _name;

        }

        public boolean isEnabled() {

            return _enabled;

        }

        public int hashCode() {

            return getName().hashCode();

        }

        public boolean equals( final Object rhs ) {

            return rhs instanceof Constraint && getName().equals( ( (Constraint)rhs ).getName() );

        }

        public int compareTo( final Constraint rhs ) {

            return getName().compareTo( rhs.getName() );

        }

        public String toString() {

            return "SimpleConstraint( \"" + getName() + "\", " + isEnabled() + " )";

        }

    }

    public static class ConstraintsTable extends TreeMap<String, Constraint> {

      public ConstraintsTable() {

            super();

        }

        public ConstraintsTable( final Constraint singletonConstraint ) {

            super();

            put( singletonConstraint.getName(), singletonConstraint );

        }

    }

    private final LinearContainer3 _target;

    private final LinearOrientation _orientation;

    private final Hashtable<Component, ConstraintsTable> _constraints = new Hashtable<>();

    private LinearLayoutManagerCache _cache;

    public LinearLayoutManager3(
            final @NotNull LinearOrientation orientation,
            final @NotNull LinearContainer3 target
    ) {

        super();

        _orientation = orientation;

        _target = target;

        preLoadCacheIfNecessary();

    }

    @Override
    public synchronized void addLayoutComponent( final Component comp, final Object xConstraints ) {

        implicitInvalidateLayout(
                ( comp == null ? "unknown" : comp.getClass().getCanonicalName() ) + " component added",
                "addLayoutComponent(Component,Object)",
                _target
        );

        if ( comp == null ) {

            throw new IllegalArgumentException(
                    "LinearLayoutManager3.addLayoutComponent( Component, Object ):  component is null"
            );

        }

        _constraints.remove( comp );
        ConstraintsTable constraints;

        if ( xConstraints == null ) {

            return;

        }

        if ( xConstraints instanceof Constraint ) {

            Constraint singletonConstraint = (Constraint)xConstraints;

            constraints = new ConstraintsTable( singletonConstraint );

        } else if ( xConstraints instanceof ConstraintsTable ) {

            constraints = (ConstraintsTable)xConstraints;

        } else {

            throw new IllegalArgumentException( "LinearLayoutManager3.addLayoutComponent( Component, Object ):  constraints not a " +
                                                ConstraintsTable.class.getCanonicalName() );

        }

        ConstraintsTable copy = new ConstraintsTable();
        for ( String key : constraints.keySet() ) {

            Constraint value = constraints.get( key );

            if ( value == null ) {

                throw new IllegalArgumentException(
                        "LinearLayoutManager3.addLayoutComponent( Component, Object ):  constraint named \"" + key + "\" is null" );

            }

            copy.put( key, value );

        }

        _constraints.put( comp, copy );

    }

    private void checkContainer( final String who, final Container target ) {

        if ( target != _target ) {

            throw new IllegalArgumentException( "LinearLayoutManager3(" +
                                                who +
                                                "):  this instance dedicated to " +
                                                _target +
                                                ", cannot be switched to " +
                                                target );

        }

    }

    private synchronized void preLoadCacheIfNecessary() {

        if ( _cache == null ) {

            _cache = new LinearCache3( this, _target, _constraints );

        }

    }

    @Override
    public synchronized float getLayoutAlignmentX( final Container target ) {

        checkContainer( "getLayoutAlignmentX", target );
        preLoadCacheIfNecessary();

        return _cache.getLayoutAlignmentX();

    }

    @Override
    public float getLayoutAlignmentY( final Container target ) {

        checkContainer( "getLayoutAlignmentY", target );
        preLoadCacheIfNecessary();

        return _cache.getLayoutAlignmentY();

    }

    private synchronized void implicitInvalidateLayout(
            @NotNull String why,
            @NotNull final String requester,
            @NotNull final LinearContainer3 target
    ) {

        if ( _cache != null && LinearLayoutUtil.isContainerOnWatchlist( _target ) ) {

            Logger.logMsg(
                    "layout invalidated by " + requester +
                    " (target is " + target + "," +
                    " why is " + ObtuseUtil.enquoteToJavaString( why ) + ")"
            );

        }

        _cache = null;

    }

    @SuppressWarnings("Duplicates")
    @Override
    public synchronized Dimension preferredLayoutSize( final Container target ) {

        checkContainer( "preferredLayoutSize", target );
        preLoadCacheIfNecessary();

        Dimension size = _cache.getPreferredSize();

        if ( "outer".equals( getTarget().getName() ) ) {

            ObtuseUtil.doNothing();

        }

        return size;

    }

    @Override
    public synchronized Dimension minimumLayoutSize( final Container target ) {

        checkContainer( "minimumLayoutSize", target );
        preLoadCacheIfNecessary();

        Dimension size = _cache.getMinimumSize();

        return size;

    }

    @Override
    public synchronized Dimension maximumLayoutSize( final Container target ) {

        checkContainer( "maximumLayoutSize", target );
        preLoadCacheIfNecessary();

        Dimension size = _cache.getMaximumSize();

        return size;

    }

    @Override
    public synchronized void invalidateLayout( final Container target ) {

        checkContainer( "invalidateLayout", target );

        implicitInvalidateLayout(
                "somebody asked nicely",
                "invalidateLayout",
                (LinearContainer3)target
        );

    }

    @Override
    public void addLayoutComponent( final String name, final Component comp ) {

        Logger.logMsg( "addLayoutComponent( " + ObtuseUtil.enquoteToJavaString( name ) + ", " + comp + " )" );

        implicitInvalidateLayout(
                ( comp == null ? "unknown" : comp.getClass().getCanonicalName() ) + " component added",
                "addLayoutComponent(String,Component)",
                _target
        );

    }

    @Override
    public synchronized void removeLayoutComponent( final Component comp ) {

        implicitInvalidateLayout(
                ( comp == null ? "unknown" : comp.getClass().getCanonicalName() ) + " component removed",
                "removeLayoutComponent",
                _target
        );

        if ( comp == null ) {

            throw new IllegalArgumentException( "LinearLayoutManager3.removeLayoutComponent( Component ):  component is null" );

        } else {

            _constraints.remove( comp );

        }

    }

    @SuppressWarnings("Duplicates")
    @Override
    public void layoutContainer( final Container parent ) {

        _cache = null;
        implicitInvalidateLayout(
                "just because",
                "layoutContainer",
                _target
        );

        LinearLayoutManagerCache cache;

        synchronized ( this ) {

            if ( LinearLayoutUtil.isContainerOnWatchlist( parent ) ) {

                ObtuseUtil.doNothing();

            }

            checkContainer( "layoutContainer", parent );

            preLoadCacheIfNecessary();

            if ( _target.isWatched() ) {

                Logger.logMsg( "doing a layout of " + _target );

                _target.doingLayout();

                ObtuseUtil.doNothing();

            }

            cache = _cache;
            _cache.computePositions();

            if ( _target.isWatched() ) {

                Logger.logMsg( "done layout of " + _target );

                _target.doneLayout();

                ObtuseUtil.doNothing();

            }

        }

        cache.setComponentBounds();

        int containerWidth = 0;
        int containerHeight = 0;

        for ( int i = 0; i < cache.getVisibleComponentCount(); i += 1 ) {

            Component c = cache.getVisibleComponent( i );
            Rectangle bounds = c.getBounds();
            containerWidth = Math.max( containerWidth, bounds.x + bounds.width );
            containerHeight = Math.max( containerHeight, bounds.y + bounds.height );

        }

    }

    public LinearOrientation getOrientation() {

        return _orientation;

    }

    public LinearContainer3 getTarget() {

        return _target;

    }

    public static void main( final String[] args ) {

        BasicProgramConfigInfo.init( "Obtuse", "LinearLayoutManager3", "testing" );

        JFrame frame = new JFrame( "test simple linear layouts" );
        LinearContainer inner = LinearLayoutUtil.getLinearContainer3( "inner", LinearOrientation.VERTICAL, true );
        inner.setBorder( BorderFactory.createEtchedBorder() );

        JButton jb1 = new JButton( "Say Hello" );
        jb1.addActionListener(
                new MyActionListener() {

                    @Override
                    public void myActionPerformed( final ActionEvent actionEvent ) {

                        Logger.logMsg( "hello" );

                    }

                }
        );
        inner.add( jb1 );

        JButton jb2 = new JButton( "Say Boo!" );
        jb2.addActionListener(
                new MyActionListener() {

                    @Override
                    public void myActionPerformed( final ActionEvent actionEvent ) {

                        Logger.logMsg( "Boo!" );

                    }

                }
        );
        inner.add( jb2 );

        LinearContainer outer = LinearLayoutUtil.getLinearContainer3( "outer", LinearOrientation.HORIZONTAL, true );
        outer.setBorder( BorderFactory.createLineBorder( Color.RED ) );
        outer.add( inner.getAsContainer() );
        JButton jb3 = new JButton( "Flip" );
        jb3.addActionListener(
                new MyActionListener() {

                    @Override
                    public void myActionPerformed( final ActionEvent actionEvent ) {

                        if ( "Flip".equals( jb3.getText() ) ) {

                            jb3.setText( "Flop" );

                        } else {

                            jb3.setText( "Flip" );

                        }

                    }

                }
        );
        JPanel inner2 = new JPanel();
        inner2.setLayout( new BoxLayout( inner2, BoxLayout.Y_AXIS ) );
        outer.add( inner2 );
        inner2.add( jb3 );
        inner2.setBorder( BorderFactory.createEtchedBorder( Color.GREEN, Color.WHITE ) );

        frame.setContentPane( outer.getAsContainer() );
        frame.pack();
        frame.setVisible( true );

        ObtuseUtil.doNothing();

    }

    public static void mainX( final String[] args ) {

        BasicProgramConfigInfo.init( "Obtuse", "Pipestone", "Testing" );

        JFrame frame = new JFrame( "LinearLayoutManager3" );
        JPanel inner = makeMainContainer(
                true,
                LinearOrientation.VERTICAL,
                null,
                new ConstraintTuple( 0, 32767 )
        );

        JScrollPane scrollPane = new JScrollPane(
                inner
        );
        scrollPane.setMaximumSize( new Dimension( 32767, 250 ) );
        scrollPane.setMinimumSize( new Dimension( 0, 250 ) );
        scrollPane.setPreferredSize( new Dimension( 0, 250 ) );

        scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS );
        scrollPane.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS );

        JPanel main = makeMainContainer(
                true,
                LinearOrientation.VERTICAL,
                new Component[]{ makeTestFiller( "blorf" ), scrollPane },
                new ConstraintTuple( 300, 600 )
        );

        Box b = new Box( BoxLayout.X_AXIS );
        b.add( main );
        b.add( new Box.Filler( new Dimension( 0, 0 ), new Dimension( 20, 20 ), new Dimension( 32767, 32767 ) ) );
        frame.setContentPane( b );
        frame.pack();
        frame.setVisible( true );

    }

    @NotNull
    public static JPanel makeMainContainer(
            @SuppressWarnings("SameParameterValue") final boolean makeLinearContainer,
            @SuppressWarnings("SameParameterValue") final LinearOrientation orientation,
            final Component[] extraComponents,
            @Nullable final ConstraintTuple breadthConstraints
    ) {

        JPanel main;
        if ( makeLinearContainer ) {

            LinearContainer3 lc3 = new LinearContainer3( "main", orientation, null, null );

            lc3.setBreadthConstraints( breadthConstraints );

            main = lc3;

        } else {

            main = new JPanel();
            main.setLayout( new BoxLayout( main, BoxLayout.Y_AXIS ) );

        }

        main.setBorder( BorderFactory.createLineBorder( Color.RED ) );
        main.setAlignmentX( 0.0f );
        main.setAlignmentY( 0.0f );

        String label = makeLinearContainer ? "linear" : "box";
        LinearLayoutUtil.makeButtons(
                main,
                1,
                label,
                new MyActionListener() {

                    @Override
                    public void myActionPerformed( final ActionEvent actionEvent ) {

                        if ( actionEvent.getSource() instanceof JButton ) {

                            JButton button = (JButton)actionEvent.getSource();

                            Logger.logMsg( "removing button " + button );
                            Container parent = button.getParent();
                            parent.remove( button );
                            parent.revalidate();

                        }

                    }

                }
        );

        if ( extraComponents != null ) {

            for ( Component extra : extraComponents ) {

                main.add( extra );

            }

        }

        JPanel filler;
        filler = makeTestFiller( label );
        filler.setDoubleBuffered( false );

        filler.setName( "filler" );
        LinearLayoutUtil.addLocationTracer( filler );
        main.add( filler );

        return main;

    }

    @NotNull
    public static JPanel makeTestFiller( final String label ) {

        JPanel filler;
        filler = new JPanel() {

            protected void paintComponent( final Graphics g ) {

                super.paintComponent( g );

                Graphics2D g2d = (Graphics2D)g;
                g2d.setColor( Color.YELLOW );
                g2d.fillRect( 0, 0, getWidth(), getHeight() );
                g2d.setColor( Color.RED );
                g2d.fillRect( 0, 0, 3, 3 );
                g2d.fillRect( getWidth() - 3, 0, 3, 3 );
                g2d.fillRect( 0, getHeight() - 3, 3, 3 );
                g2d.fillRect( getWidth() - 3, getHeight() - 3, 3, 3 );
                g2d.setColor( Color.BLACK );
                Insets insets = getInsets();
                int left = insets.left;
                int top = insets.top;
                int right = getWidth() -
                            insets.right -
                            1;    // subtracting 1 accounts for fact that last pixel in a n pixel wide space is at location n-1
                int bottom = getHeight() -
                             insets.bottom -
                             1;    // subtracting 1 accounts for fact that last pixel in a n pixel wide space is at location n-1

                String l1msg = LinearLayoutUtil.myDrawLine( "filler1", g2d, left, top, right, bottom );
                String l2msg = LinearLayoutUtil.myDrawLine( "filler2", g2d, left, bottom, right, 1 );

                ObtuseUtil.doNothing();

            }

        };

        return filler;

    }

    public String toString() {

        return "LinearLayoutManager3( orientation=" + getOrientation() + ", container=" + getTarget() + " )";

    }

}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Linzer biol. Beitr. 30(2): 832 (1998)

#### Original name
Verrucaria truncigena Breuss

### Remarks
null


text:
/**
 * Created by PC on 05.05.2016 г..
 */
angular.module('issueTrackingSystem.issue.issueService', [])
    .factory('issueService', [
        '$http',
        '$q',
        'BASE_URL',
        function issueService($http, $q, BASE_URL) {
            /*function getCurrentIssue(issueId) {
                var deferred = $q.defer(),
                    getCurrentIssueUrl = BASE_URL + 'Issues/' + issueId;

                $http.get(getCurrentIssueUrl)
                    .then(function(currentIssue) {
                        deferred.resolve(currentIssue);
                    },
                    function(error) {
                        deferred.reject(error);
                    });

                return deferred.promise;
            }*/

            function getComments(issueId) {
                var deferred = $q.defer(),
                    getCommentsUrl = BASE_URL + 'Issues/' + issueId + '/comments';

                $http.get(getCommentsUrl)
                    .then(function(comments) {
                        console.log(comments);
                        deferred.resolve(comments);
                    },
                    function(error) {
                        deferred.reject(error);
                    });

                return deferred.promise;
            }

            function addComment(issueId, newComment) {
                var deferred = $q.defer(),
                    addCommentUrl = BASE_URL + 'Issues/' + issueId + '/comments',
                    requestBody = {
                        Text: newComment
                    };

                $http.post(addCommentUrl, requestBody)
                    .then(function(allComments) {
                        console.log(allComments);
                        deferred.resolve(allComments);
                    },
                    function(error) {
                        deferred.reject(error);
                    });

                return deferred.promise;
            }

            function changeStatus(issueId, newStatusId) {
                var deferred = $q.defer(),
                    changeStatusUrl = BASE_URL + 'Issues/' + issueId + '/changestatus?statusid=' + newStatusId;

                $http.put(changeStatusUrl)
                    .then(function(newAvailableStatuses) {
                        deferred.resolve(newAvailableStatuses);
                    },
                    function(error) {
                        deferred.reject(error);
                    });

                return deferred.promise;
            }

            return {
                //getCurrentIssue: getCurrentIssue,
                getComments: getComments,
                addComment: addComment,
                changeStatus: changeStatus
            }
        }]);


text:
package _5_2_verteilter_hash_join;

import java.io.Serializable;

public class Register implements Serializable{
	private static final long serialVersionUID = 1L;
	public String[] states = {"Unbound", "Int", "Double", "Bool", "String"};
	private String state;
	int intValue;
	boolean boolValue;
	String stringValue;
	double doubleValue;

	public Register(){
		state = "Unbound";
	}

	//setter
	public void setUnbound() { state="Unbound"; }
	public void setInt(int value) { state="Int"; intValue=value;}
	public void setDouble(double value) { state="Double"; doubleValue=value;}
	public void setBool(boolean value) { state="Bool"; boolValue=value;}
	public void setString(String value) { state="String"; stringValue=value;}

	//getter
	public String getState(){
		return this.state;
	}
	public int getInt(){
		return intValue;
	}
	public double getDouble(){
		return doubleValue;
	}
	public boolean getBool(){
		return boolValue;
	}
	public String getString(){
		return stringValue;
	}

	public Object getObject(){
		switch (state) {
	      case "Unbound": return null;
	      case "Int": return intValue;
	      case "Double": return doubleValue;
	      case "Bool": return boolValue;
	      case "String": return stringValue;
	   }
		return null;
	}

	public boolean operator_gleich(Register r){
		// Make sure that the state is the same
	   if (!state.equals(r.state))
	      return false;

	   // Compare
	   switch (state) {
	      case "Unbound": return true;
	      case "Int": return intValue==r.intValue;
	      case "Double": return doubleValue==r.doubleValue;
	      case "Bool": return boolValue==r.boolValue;
	      case "String": return stringValue.equals(r.stringValue);
	   }
	   return false;
	}
	public boolean operator_kleiner(Register r){
		// Make sure that the state is the same
	   if (!state.equals(r.state))
	      return false;

	   // Compare
	   switch (state) {
	      case "Unbound": return true;
	      case "Int": return intValue<r.intValue;
	      case "Double": return doubleValue<r.doubleValue;
	      case "Bool": return false;
	      case "String": return false;
	   }
	   return false;
	}

	@Override
	public String toString(){
		String ret = ""; 		//state + " ";
		switch (state) {
	      case "Int": ret+= intValue;break;
	      case "Double": ret+= doubleValue;break;
	      case "Bool": ret+= boolValue;break;
	      case "String": ret+= stringValue;break;
	   }
		return ret;
	}

	@Override
	public boolean equals(Object obj){
		if(obj instanceof Register){
			Register r = (Register) obj;
			return this.operator_gleich(r);
		}
		return false;
	}
}


text:
<?php

/*
 * This file is part of the FunkitonInjector bundle
 *
 * (c) Lenar Lõhmus <lenar@city.ee>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace Funkiton\InjectorBundle\Service;

use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;

/**
 * The Injector class does the real injection
 *
 * @author Lenar Lõhmus <lenar@city.ee>
 */
class Injector
{
    /**
     * @var Symfony\Component\DependencyInjection\ContainerInterface
     */
    protected $container;

    /**
     * @var Array
     */
    protected $definitions;

    /**
     * Constructor.
     *
     * @param ContainerInterface $container A service container
     */
    public function __construct(array $definitions, ContainerInterface $container)
    {
        $this->container = $container;
        $this->definitions = $definitions;
    }

    /**
     * Injects service into target object
     *
     * @param String $name Property name of target Object
     * @param String $service Service name to inject (either service.name or service.name::someMethod)
     * @param String $targetObject Object to retrieve the injection
     */
    public function inject($name, $service, $targetObject) {
        $value = null;
        if (null !== $service) {
            if (isset($this->definitions[$service])) {
                $service = $this->definitions[$service];
            }
            $method = null;
            if (false !== strpos($service, '::')) {
                list($service, $method) = explode('::', $service, 2);
            }

            if (!is_object($value = $this->container->get($service, true))) {
                throw new ServiceNotFoundException(sprintf('You have requested a non-existent service "%s"', $service));
            }
            if (null !== $method) {
                if (!method_exists($value, $method)) {
                    throw new RuntimeException(sprintf('Service "%s" does not have method "%s"', $service, $method));
                }
                $value = $value->$method();
                if (!is_object($value)) {
                    throw new RuntimeException(sprintf('Service %s::%s is not an object', $service, $method));
                }
            }
        }
        if (property_exists($class = get_class($targetObject), $name)) {
            $property = new \ReflectionProperty($class, $name);
            $property->setAccessible(true);
            $property->setValue($targetObject, $value);
        } else {
           $targetObject->$name = $value;
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external_files"
        path="multipleImagePickerLib/files" />
</paths>


text:
package com.baidu.oped.apm.profiler.interceptor.registry;

import com.baidu.oped.apm.bootstrap.interceptor.registry.DefaultInterceptorRegistryAdaptor;
import com.baidu.oped.apm.bootstrap.interceptor.registry.InterceptorRegistry;
import com.baidu.oped.apm.bootstrap.interceptor.registry.InterceptorRegistryAdaptor;

/**
 * @author emeroad
 */
public class DefaultInterceptorRegistryBinder implements InterceptorRegistryBinder {

    private final Object lock;
    private final InterceptorRegistryAdaptor interceptorRegistryAdaptor = new DefaultInterceptorRegistryAdaptor();

    public DefaultInterceptorRegistryBinder() {
        this.lock = new Object();
    }

    @Override
    public void bind() {
        InterceptorRegistry.bind(interceptorRegistryAdaptor, lock);
    }

    @Override
    public void unbind() {
        InterceptorRegistry.unbind(lock);
    }

    public InterceptorRegistryAdaptor getInterceptorRegistryAdaptor() {
        return interceptorRegistryAdaptor;
    }

    @Override
    public String getInterceptorRegistryClassName() {
        return InterceptorRegistry.class.getName();
    }
}