[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/cpplearner/cpputil/master/invoke.hpp [Back]  [Original]

#pragma once

#include 
#include 

#include "is_reference_wrapper.hpp"

template
struct invoke_impl {
    template
    static constexpr auto call(F&& f, Args&&... args)
        noexcept(noexcept(static_cast(f)(static_cast(args)...)))
        -> decltype(static_cast(f)(static_cast(args)...))
    { return static_cast(f)(static_cast(args)...); }
};

template
struct invoke_impl {
    template
    static constexpr auto get(T&& t) noexcept -> T&&
    { return static_cast(t); }

    template
    static constexpr auto get(T&& t) noexcept -> decltype(t.get())
    { return t.get(); }

    template>,
        class = std::enable_if_t>>
    >
    static constexpr auto get(T&& t)
        noexcept(noexcept(*static_cast(t)))
        -> decltype(*static_cast(t))
    { return *static_cast(t); }

    template
    static constexpr auto call(AA B::*pmf, T&& t, Args&&... args)
        noexcept(noexcept(((get)(static_cast(t)).*pmf)(static_cast(args)...)))
        -> decltype(((get)(static_cast(t)).*pmf)(static_cast(args)...))
    { return ((get)(static_cast(t)).*pmf)(static_cast(args)...); }

    template
    static constexpr auto call(A B::*pmd, T&& t)
        noexcept(noexcept((get)(static_cast(t)).*pmd))
        -> decltype((get)(static_cast(t)).*pmd)
    { return (get)(static_cast(t)).*pmd; }
};

template
constexpr auto invoke(F&& f, Args&&... args)
    noexcept(noexcept(invoke_impl::call(
            static_cast(f), static_cast(args)...)))
    -> decltype(invoke_impl::call(
            static_cast(f), static_cast(args)...))
{
    return invoke_impl::call(
        static_cast(f), static_cast(args)...);
}

template
constexpr R invoke(F&& f, Args&&... args)
    noexcept(noexcept(invoke_impl::call(
        static_cast(f), static_cast(args)...)) &&
        (std::is_void_v || std::is_nothrow_convertible_v))
{
    if constexpr (!std::is_void_v)
        return invoke_impl::call(
            static_cast(f), static_cast(args)...);
    else
        invoke_impl::call(
            static_cast(f), static_cast(args)...);
}

Web Proxy Viewer  |  New URL  |  Original Page