traits: use a less verbose workaround for life_traits ODR issues

This commit is contained in:
Danny Robson 2017-09-08 17:34:56 +10:00
parent 32a7f6e816
commit c5591d654a

View File

@ -138,67 +138,69 @@ namespace cruft::vk {
/// XXX: if such a function does not exist anywhere then we currently use
/// tuple::ignore to simplify implementation elsewhere. we should probably
/// investigate std::is_detected for these cases though.
///
/// clang#18781: we make use of references types extensively here to
/// workaround a potential ODR bug in clang which results in undefined
/// references.
/// or potentially i'm being too clever for my own good, but it works fine
/// in gcc...
template <typename>
struct life_traits { };
//-------------------------------------------------------------------------
template <> struct life_traits<instance> {
static constexpr auto create = vkCreateInstance;
static constexpr auto destroy = vkDestroyInstance;
static constexpr auto& create = vkCreateInstance;
static constexpr auto& destroy = vkDestroyInstance;
};
template <> struct life_traits<device> {
static constexpr auto create = vkCreateDevice;
static constexpr auto destroy = vkDestroyDevice;
static constexpr auto& create = vkCreateDevice;
static constexpr auto& destroy = vkDestroyDevice;
};
template <> struct life_traits<command_pool> {
static constexpr auto create = vkCreateCommandPool;
static constexpr auto destroy = vkDestroyCommandPool;
static constexpr auto& create = vkCreateCommandPool;
static constexpr auto& destroy = vkDestroyCommandPool;
};
template <> struct life_traits<fence> {
static constexpr auto create = vkCreateFence;
static constexpr auto destroy = vkDestroyFence;
static constexpr auto& create = vkCreateFence;
static constexpr auto& destroy = vkDestroyFence;
};
template <> struct life_traits<semaphore> {
static constexpr auto create = vkCreateSemaphore;
static constexpr auto destroy = vkDestroySemaphore;
static constexpr auto& create = vkCreateSemaphore;
static constexpr auto& destroy = vkDestroySemaphore;
};
template <> struct life_traits<event> {
static constexpr auto create = vkCreateEvent;
static constexpr auto destroy = vkDestroyEvent;
static constexpr auto& create = vkCreateEvent;
static constexpr auto& destroy = vkDestroyEvent;
};
template <> struct life_traits<render_pass> {
static constexpr auto create = vkCreateRenderPass;
static constexpr auto destroy = vkDestroyRenderPass;
static constexpr auto& create = vkCreateRenderPass;
static constexpr auto& destroy = vkDestroyRenderPass;
};
template <> struct life_traits<framebuffer> {
static constexpr auto create = vkCreateFramebuffer;
static constexpr auto destroy = vkDestroyFramebuffer;
static constexpr auto& create = vkCreateFramebuffer;
static constexpr auto& destroy = vkDestroyFramebuffer;
};
template <> struct life_traits<shader_module> {
static constexpr auto create = vkCreateShaderModule;
static constexpr auto destroy = vkDestroyShaderModule;
static constexpr auto& create = vkCreateShaderModule;
static constexpr auto& destroy = vkDestroyShaderModule;
};
template <> struct life_traits<surface> {
static constexpr auto destroy = vkDestroySurfaceKHR;
static constexpr auto& destroy = vkDestroySurfaceKHR;
};
template <>
struct life_traits<queue> {
// clang#18781: we work around an ODR bug in clang which causes
// undefined references by explicitly using a temporary here. ideally
// this causes minimal difference in the generated output.
using create_t = decltype(vkGetDeviceQueue);
static constexpr create_t& create = vkGetDeviceQueue;
static constexpr auto& create = vkGetDeviceQueue;
static constexpr auto destroy = ::util::tuple::ignore<
id_t<owner_t<queue>>,
@ -225,22 +227,22 @@ namespace cruft::vk {
//};
template <> struct life_traits<pipeline_cache> {
static constexpr auto create = vkCreatePipelineCache;
static constexpr auto destroy = vkDestroyPipelineCache;
static constexpr auto& create = vkCreatePipelineCache;
static constexpr auto& destroy = vkDestroyPipelineCache;
};
template <> struct life_traits<device_memory> {
static constexpr auto create = vkAllocateMemory;
static constexpr auto destroy = vkFreeMemory;
static constexpr auto& create = vkAllocateMemory;
static constexpr auto& destroy = vkFreeMemory;
};
template <> struct life_traits<buffer> {
static constexpr auto create = vkCreateBuffer;
static constexpr auto destroy = vkDestroyBuffer;
static constexpr auto& create = vkCreateBuffer;
static constexpr auto& destroy = vkDestroyBuffer;
};
template <> struct life_traits<buffer_view> {
static constexpr auto create = vkCreateBufferView;
static constexpr auto& create = vkCreateBufferView;
};