// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef LIB_FIDL_INTERNAL_CALLABLE_TRAITS_H_
#define LIB_FIDL_INTERNAL_CALLABLE_TRAITS_H_

#include <tuple>
#include <type_traits>

namespace fidl {

namespace internal {

// |callable_traits| captures elements of interest from function-like types (functions, function
// pointers, and functors, including lambdas). Due to common usage patterns, const and non-const
// functors are treated identically.
//
// Member types:
//  |args|        - a |std::tuple| that captures the parameter types of the function.
//  |return_type| - the return type of the function.
//  |type|        - the underlying functor or function pointer type. This member is absent if
//                  |callable_traits| are requested for a raw function signature (as opposed to a
//                  function pointer or functor; e.g. |callable_traits<void()>|).
//  |signature|   - the type of the equivalent function.

template <typename T>
struct callable_traits : public callable_traits<decltype(&T::operator())> {};

// Treat mutable call operators the same as const call operators.
//
// It would be equivalent to erase the const instead, but the common case is lambdas, which are
// const, so prefer to nest less deeply for the common const case.
template <typename FunctorType, typename ReturnType, typename... ArgTypes>
struct callable_traits<ReturnType (FunctorType::*)(ArgTypes...)>
    : public callable_traits<ReturnType (FunctorType::*)(ArgTypes...) const> {};

// Common functor specialization.
template <typename FunctorType, typename ReturnType, typename... ArgTypes>
struct callable_traits<ReturnType (FunctorType::*)(ArgTypes...) const>
    : public callable_traits<ReturnType (*)(ArgTypes...)> {

    using type = FunctorType;
};

// Function pointer specialization.
template <typename ReturnType, typename... ArgTypes>
struct callable_traits<ReturnType (*)(ArgTypes...)>
    : public callable_traits<ReturnType(ArgTypes...)> {

    using type = ReturnType (*)(ArgTypes...);
};

// Base specialization.
template <typename ReturnType, typename... ArgTypes>
struct callable_traits<ReturnType(ArgTypes...)> {
    using signature = ReturnType(ArgTypes...);
    using return_type = ReturnType;
    using args = std::tuple<ArgTypes...>;

    callable_traits() = delete;
};

template <typename FuncA, typename FuncB>
struct SameInterfaceImpl {
    static constexpr bool args_equal =
        std::is_same<
            typename callable_traits<FuncA>::args,
            typename callable_traits<FuncB>::args>::value;

    static constexpr bool return_equal =
        std::is_same<
            typename callable_traits<FuncA>::return_type,
            typename callable_traits<FuncB>::return_type>::value;

    static constexpr bool value = args_equal && return_equal;
};

template <typename FuncA, typename FuncB>
constexpr bool SameInterface = SameInterfaceImpl<FuncA, FuncB>::value;

template <typename FuncA, typename FuncB>
constexpr bool SameArguments = SameInterfaceImpl<FuncA, FuncB>::args_equal;

} // namespace internal

} // namespace fidl

#endif // LIB_FIDL_INTERNAL_CALLABLE_TRAITS_H_
