// Copyright (c) 2011 The Chromium 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 BASE_BIND_H_
#define BASE_BIND_H_

#include "base/bind_internal.h"
#include "base/callback_internal.h"

// -----------------------------------------------------------------------------
// Usage documentation
// -----------------------------------------------------------------------------
//
// See base/callback.h for documentation.
//
//
// -----------------------------------------------------------------------------
// Implementation notes
// -----------------------------------------------------------------------------
//
// If you're reading the implementation, before proceeding further, you should
// read the top comment of base/bind_internal.h for a definition of common
// terms and concepts.
//
// RETURN TYPES
//
// Though Bind()'s result is meant to be stored in a Callback<> type, it
// cannot actually return the exact type without requiring a large amount
// of extra template specializations. The problem is that in order to
// discern the correct specialization of Callback<>, Bind would need to
// unwrap the function signature to determine the signature's arity, and
// whether or not it is a method.
//
// Each unique combination of (arity, function_type, num_prebound) where
// function_type is one of {function, method, const_method} would require
// one specialization.  We eventually have to do a similar number of
// specializations anyways in the implementation (see the Invoker<>,
// classes).  However, it is avoidable in Bind if we return the result
// via an indirection like we do below.
//
// TODO(ajwong): We might be able to avoid this now, but need to test.
//
// It is possible to move most of the static_assert into BindState<>, but it
// feels a little nicer to have the asserts here so people do not need to crack
// open bind_internal.h.  On the other hand, it makes Bind() harder to read.

namespace base {

template <typename Functor>
base::Callback<
    typename internal::BindState<
        typename internal::FunctorTraits<Functor>::RunnableType,
        typename internal::FunctorTraits<Functor>::RunType,
        void()>::UnboundRunType>
Bind(Functor functor) {
  // Typedefs for how to store and run the functor.
  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
  typedef typename internal::FunctorTraits<Functor>::RunType RunType;

  typedef internal::BindState<RunnableType, RunType, void()> BindState;

  return Callback<typename BindState::UnboundRunType>(
      new BindState(internal::MakeRunnable(functor)));
}

template <typename Functor, typename... Args>
base::Callback<
    typename internal::BindState<
        typename internal::FunctorTraits<Functor>::RunnableType,
        typename internal::FunctorTraits<Functor>::RunType,
        void(typename internal::CallbackParamTraits<Args>::StorageType...)>
            ::UnboundRunType>
Bind(Functor functor, const Args&... args) {
  // Typedefs for how to store and run the functor.
  typedef typename internal::FunctorTraits<Functor>::RunnableType RunnableType;
  typedef typename internal::FunctorTraits<Functor>::RunType RunType;

  // Use RunnableType::RunType instead of RunType above because our
  // checks should below for bound references need to know what the actual
  // functor is going to interpret the argument as.
  typedef typename RunnableType::RunType BoundRunType;

  // Do not allow binding a non-const reference parameter. Non-const reference
  // parameters are disallowed by the Google style guide.  Also, binding a
  // non-const reference parameter can make for subtle bugs because the
  // invoked function will receive a reference to the stored copy of the
  // argument and not the original.
  static_assert(!internal::HasNonConstReferenceParam<BoundRunType>::value,
                "do_not_bind_functions_with_nonconst_ref");

  const bool is_method = internal::HasIsMethodTag<RunnableType>::value;

  // For methods, we need to be careful for parameter 1.  We do not require
  // a scoped_refptr because BindState<> itself takes care of AddRef() for
  // methods. We also disallow binding of an array as the method's target
  // object.
  static_assert(!internal::BindsArrayToFirstArg<is_method, Args...>::value,
                "first_bound_argument_to_method_cannot_be_array");
  static_assert(
      !internal::HasRefCountedParamAsRawPtr<is_method, Args...>::value,
      "a_parameter_is_refcounted_type_and_needs_scoped_refptr");

  typedef internal::BindState<RunnableType, RunType,
      void(typename internal::CallbackParamTraits<Args>::StorageType...)>
      BindState;

  return Callback<typename BindState::UnboundRunType>(
      new BindState(internal::MakeRunnable(functor), args...));
}

}  // namespace base

#endif  // BASE_BIND_H_
