#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