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 /// XXX: if such a function does not exist anywhere then we currently use
/// tuple::ignore to simplify implementation elsewhere. we should probably /// tuple::ignore to simplify implementation elsewhere. we should probably
/// investigate std::is_detected for these cases though. /// 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> template <typename>
struct life_traits { }; struct life_traits { };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
template <> struct life_traits<instance> { template <> struct life_traits<instance> {
static constexpr auto create = vkCreateInstance; static constexpr auto& create = vkCreateInstance;
static constexpr auto destroy = vkDestroyInstance; static constexpr auto& destroy = vkDestroyInstance;
}; };
template <> struct life_traits<device> { template <> struct life_traits<device> {
static constexpr auto create = vkCreateDevice; static constexpr auto& create = vkCreateDevice;
static constexpr auto destroy = vkDestroyDevice; static constexpr auto& destroy = vkDestroyDevice;
}; };
template <> struct life_traits<command_pool> { template <> struct life_traits<command_pool> {
static constexpr auto create = vkCreateCommandPool; static constexpr auto& create = vkCreateCommandPool;
static constexpr auto destroy = vkDestroyCommandPool; static constexpr auto& destroy = vkDestroyCommandPool;
}; };
template <> struct life_traits<fence> { template <> struct life_traits<fence> {
static constexpr auto create = vkCreateFence; static constexpr auto& create = vkCreateFence;
static constexpr auto destroy = vkDestroyFence; static constexpr auto& destroy = vkDestroyFence;
}; };
template <> struct life_traits<semaphore> { template <> struct life_traits<semaphore> {
static constexpr auto create = vkCreateSemaphore; static constexpr auto& create = vkCreateSemaphore;
static constexpr auto destroy = vkDestroySemaphore; static constexpr auto& destroy = vkDestroySemaphore;
}; };
template <> struct life_traits<event> { template <> struct life_traits<event> {
static constexpr auto create = vkCreateEvent; static constexpr auto& create = vkCreateEvent;
static constexpr auto destroy = vkDestroyEvent; static constexpr auto& destroy = vkDestroyEvent;
}; };
template <> struct life_traits<render_pass> { template <> struct life_traits<render_pass> {
static constexpr auto create = vkCreateRenderPass; static constexpr auto& create = vkCreateRenderPass;
static constexpr auto destroy = vkDestroyRenderPass; static constexpr auto& destroy = vkDestroyRenderPass;
}; };
template <> struct life_traits<framebuffer> { template <> struct life_traits<framebuffer> {
static constexpr auto create = vkCreateFramebuffer; static constexpr auto& create = vkCreateFramebuffer;
static constexpr auto destroy = vkDestroyFramebuffer; static constexpr auto& destroy = vkDestroyFramebuffer;
}; };
template <> struct life_traits<shader_module> { template <> struct life_traits<shader_module> {
static constexpr auto create = vkCreateShaderModule; static constexpr auto& create = vkCreateShaderModule;
static constexpr auto destroy = vkDestroyShaderModule; static constexpr auto& destroy = vkDestroyShaderModule;
}; };
template <> struct life_traits<surface> { template <> struct life_traits<surface> {
static constexpr auto destroy = vkDestroySurfaceKHR; static constexpr auto& destroy = vkDestroySurfaceKHR;
}; };
template <> template <>
struct life_traits<queue> { struct life_traits<queue> {
// clang#18781: we work around an ODR bug in clang which causes static constexpr auto& create = vkGetDeviceQueue;
// 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 destroy = ::util::tuple::ignore< static constexpr auto destroy = ::util::tuple::ignore<
id_t<owner_t<queue>>, id_t<owner_t<queue>>,
@ -225,22 +227,22 @@ namespace cruft::vk {
//}; //};
template <> struct life_traits<pipeline_cache> { template <> struct life_traits<pipeline_cache> {
static constexpr auto create = vkCreatePipelineCache; static constexpr auto& create = vkCreatePipelineCache;
static constexpr auto destroy = vkDestroyPipelineCache; static constexpr auto& destroy = vkDestroyPipelineCache;
}; };
template <> struct life_traits<device_memory> { template <> struct life_traits<device_memory> {
static constexpr auto create = vkAllocateMemory; static constexpr auto& create = vkAllocateMemory;
static constexpr auto destroy = vkFreeMemory; static constexpr auto& destroy = vkFreeMemory;
}; };
template <> struct life_traits<buffer> { template <> struct life_traits<buffer> {
static constexpr auto create = vkCreateBuffer; static constexpr auto& create = vkCreateBuffer;
static constexpr auto destroy = vkDestroyBuffer; static constexpr auto& destroy = vkDestroyBuffer;
}; };
template <> struct life_traits<buffer_view> { template <> struct life_traits<buffer_view> {
static constexpr auto create = vkCreateBufferView; static constexpr auto& create = vkCreateBufferView;
}; };