diff --git a/common/ptr_selector.hh b/common/ptr_selector.hh new file mode 100644 index 0000000..73bdb32 --- /dev/null +++ b/common/ptr_selector.hh @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include "nf7.hh" + + +namespace nf7 { + +template +struct PtrSelector final { + public: + PtrSelector(const std::type_info& t) noexcept : type_(&t) { } + PtrSelector(const PtrSelector&) = delete; + PtrSelector(PtrSelector&&) = delete; + PtrSelector& operator=(const PtrSelector&) = delete; + PtrSelector& operator=(PtrSelector&&) = delete; + + template + Base* Select(T1 ptr1, T2... ptr2) noexcept { + auto ptr = Get(ptr1); + return ptr? ptr: Select(ptr2...); + } + Base* Select() noexcept { return nullptr; } + + private: + template + Base* Get(T ptr) const noexcept { + if constexpr (std::is_base_of>::value) { + if (*type_ == typeid(I1)) return static_cast(ptr); + } + return Get(ptr); + } + template + Base* Get(T) const noexcept { return nullptr; } + + const std::type_info* const type_; +}; + +template +using InterfaceSelector = PtrSelector; + +} // namespace nf7