// bslalg_functoradapter.h                                            -*-C++-*-
#ifndef INCLUDED_BSLALG_FUNCTORADAPTER
#define INCLUDED_BSLALG_FUNCTORADAPTER

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide an utility that adapts callable objects to functors.
//
//@CLASSES:
//   bslalg::FunctorAdapter: utility for using callable objects as functors
//
//@SEE_ALSO: bslstl_setcomparator, bslstl_mapcomparator
//
//@DESCRIPTION: This component provides a single utility template,
// `FunctorAdapter`, that adapts a parameterized adaptee type, which can be any
// callable object type, to a target functor type.  This adaptation enables a
// client to inherit from the target functor type even if the adaptee callable
// object type is a function pointer type.  This is particularly useful if the
// client of the callable object type wants to take advantage of the empty-base
// optimization to avoid paying storage cost when the callable object type is a
// functor type with no data members.
//
// `FunctorAdapter` defines an alias to the target functor type.  If the
// adaptee type is a functor type, the target type is an alias to the adaptee
// type.  If the adaptee type is a function pointer type, the target type is a
// functor type that delegates to a function referred to by a function pointer
// of the adaptee type.
//
///Usage
///-----
// This section illustrates the intended use of this component.
//
///Example 1: Using function pointer base for an empty-base optimized class
/// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Suppose that we wanted to define a binder that binds a binary predicate of a
// parameterized type to a value passed on construction.  Also suppose that we
// wanted to use the empty-base optimization to avoid paying storage cost when
// the predicate type is a functor type with no data members.  Unfortunately,
// the binary predicate type may be a function pointer type, which cannot serve
// as a base class.  The solution is to have the binder inherit from
// `FunctorAdapter::Type`, which adapts a function pointer type to a functor
// type that is a suitable base class.
//
// First, we define the class `Bind2ndInteger`, which inherits from
// `FunctorAdapter::Type` to take advantage of the empty-base optimization:
// ```
// /// This class provides a functor that delegate its function-call
// /// operator to the parameterized `BINARY_PREDICATE`, passing the user
// /// supplied parameter as the first argument and the integer value
// /// passed on construction as the second argument.
// template <class BINARY_PREDICATE>
// class Bind2ndInteger : private FunctorAdapter<BINARY_PREDICATE>::Type {
//
//     // DATA
//     int d_bondValue;  // the bound value
//
//     // NOT IMPLEMENTED
//     Bind2ndInteger(const Bind2ndInteger&);
//     Bind2ndInteger& operator=(const Bind2ndInteger&);
//
//   public:
//     // CREATORS
//
//     /// Create a `Bind2ndInteger` object that will bind the second
//     /// parameter of the specified `predicate` with the specified
//     /// integer `value`.
//     Bind2ndInteger(int value, const BINARY_PREDICATE& predicate);
//
//     /// Destroy this object.
//     //! ~Bind2ndInteger() = default;
//
//     // ACCESSORS
//
//     /// Return the result of calling the parameterized
//     /// `BINARY_PREDICATE` passing the specified `value` as the first
//     /// argument and the integer value passed on construction as the
//     /// second argument.
//     bool operator() (const int value) const;
// };
// ```
//  Then, we implement the methods of the `Bind2ndInteger` class:
// ```
// template <class BINARY_PREDICATE>
// Bind2ndInteger<BINARY_PREDICATE>::Bind2ndInteger(int value,
//                                         const BINARY_PREDICATE& predicate)
// : FunctorAdapter<BINARY_PREDICATE>::Type(predicate), d_bondValue(value)
// {
// }
// ```
// Here, we implement the `operator()` member function that simply delegates to
// `BINARY_PREDICATE`
// ```
// template <class BINARY_PREDICATE>
// bool Bind2ndInteger<BINARY_PREDICATE>::operator() (const int value) const
// {
//     const BINARY_PREDICATE& predicate = *this;
//     return predicate(value, d_bondValue);
// }
// ```
// Next, we define a function, `intCompareFunction`, that compares two
// integers:
// ```
// bool intCompareFunction(const int lhs, const int rhs)
// {
//     return lhs < rhs;
// }
// ```
// Now, we define a `Bind2ndInteger` object `functorLessThan10` using the
// `std::less<int>` functor as the parameterized `BINARY_PREDICATE` and invoke
// the function call operator:
// ```
// Bind2ndInteger<std::less<int> > functorLessThan10(10, std::less<int>());
//
// assert(functorLessThan10(1));
// assert(!functorLessThan10(12));
// ```
// Finally, we define a `Bind2ndInteger` object `functionLessThan10` passing
// the address of `intCompareFunction` on construction and invoke the function
// call operator:
// ```
// Bind2ndInteger<bool (*)(const int, const int)>
//                                functionLessThan10(10, &intCompareFunction);
//
// assert(functionLessThan10(1));
// assert(!functionLessThan10(12));
// ```

#include <bslscm_version.h>

#include <bslmf_assert.h>
#include <bslmf_functionpointertraits.h>

#include <bsls_assert.h>

namespace BloombergLP {
namespace bslalg {

                    // ====================================
                    // class FunctorAdapter_FunctionPointer
                    // ====================================

/// This class provides a functor that delegates to the function referred to
/// by a function pointer supplied on construction.  Delegation is supported
/// through the conversion operator, which implicitly returns a reference to
/// the parameterized `FUNCTION_POINTER`.
template <class FUNCTION_POINTER>
class FunctorAdapter_FunctionPointer {

  private:
    // DATA
    FUNCTION_POINTER d_function_p;  // the pointer to the function

  public:
    // CREATORS

    /// Create a `FunctorAdapter_FunctionPointer` object that will delegate
    /// to the function referred to by the specified `functionPtr`.
    explicit FunctorAdapter_FunctionPointer(FUNCTION_POINTER functionPtr);

    // MANIPULATORS

    /// Convert this object to the parameterized `FUNCTION_POINTER` by
    /// returning the function pointer supplied on construction.
    operator FUNCTION_POINTER& ();

    // ACCESSORS

    /// Convert this object to the parameterized `FUNCTION_POINTER` by
    /// returning the function pointer supplied on construction.
    operator const FUNCTION_POINTER& () const;
};

                    // ====================
                    // class FunctorAdapter
                    // ====================

/// This class provides a metafunction that defines an alias `Type` for the
/// parameterized `CALLABLE_OBJECT`.  `Type` is functor type that provides
/// the same operation as the parameterized `CALLABLE_OBJECT`.  Note that
/// function pointers are supported through a specialization of this
/// template.
template <class CALLABLE_OBJECT>
class FunctorAdapter {

  public:
    // PUBLIC TYPES

    /// This `typedef` is an alias for the functor.
    typedef CALLABLE_OBJECT Type;
};

                    // ====================
                    // class FunctorAdapter
                    // ====================

/// This specialization of `FunctorAdapter` defines an alias `Type` for a
/// functor that delegates to a function pointer matching the parameterized
/// `FUNCTION` type.
template <class FUNCTION>
class FunctorAdapter<FUNCTION*> {

    BSLMF_ASSERT(bslmf::IsFunctionPointer<FUNCTION*>::value);
        // This 'BSLMF_ASSERT' statement ensures that the parameter 'FUNCTION'
        // must be a function pointer.

  public:
    // PUBLIC TYPES

    /// This `typedef` is an alias for a functor that delegates to the function
    /// referred to by the function pointer matching the parameterized
    /// `FUNCTION` type.
    typedef FunctorAdapter_FunctionPointer<FUNCTION*> Type;
};


// ============================================================================
//                  TEMPLATE AND INLINE FUNCTION DEFINITIONS
// ============================================================================

                    // ------------------------------------
                    // class FunctorAdapter_FunctionPointer
                    // ------------------------------------

// CREATORS
template <class FUNCTION_POINTER>
inline
FunctorAdapter_FunctionPointer<FUNCTION_POINTER>
::FunctorAdapter_FunctionPointer(FUNCTION_POINTER functionPtr)
:d_function_p(functionPtr)
{
}

// MANIPULATORS
template <class FUNCTION_POINTER>
inline
FunctorAdapter_FunctionPointer<FUNCTION_POINTER>
::operator FUNCTION_POINTER& ()
{
    return d_function_p;
}

// ACCESSORS
template <class FUNCTION_POINTER>
inline
FunctorAdapter_FunctionPointer<FUNCTION_POINTER>
::operator const FUNCTION_POINTER& () const
{
    return d_function_p;
}

}  // close package namespace
}  // close enterprise namespace


#endif

// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------
