Skip to content

File overload_cast.h

File List > module > utility > src > scl > utility > type_traits > overload_cast.h

Go to the documentation of this file

#pragma once

#include <type_traits>

namespace scl::detail
{
    template <class... Args>
    struct overload_cast
    {
        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...)) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) &) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) & noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) &&) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) && noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) const) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) const &) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const & noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) const &&) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const && noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) volatile) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) volatile noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) volatile &) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) volatile & noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto operator()(R (Class::*ptr)(Args...) volatile &&) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) volatile && noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const volatile) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const volatile noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const volatile &) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const volatile & noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const volatile &&) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class Class, class R>
        constexpr auto
        operator()(R (Class::*ptr)(Args...) const volatile && noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }

        template <class R>
        constexpr auto operator()(R (*ptr)(Args...)) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
        template <class R>
        constexpr auto operator()(R (*ptr)(Args...) noexcept) const noexcept -> decltype(ptr)
        {
            return ptr;
        }
    };
} // namespace scl::detail

namespace scl
{
    template <class... Args>
    inline constexpr detail::overload_cast<Args...> overload_cast{};

} // namespace scl