Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_FUNCTION_TYPES_H
Toshihiro Shimizu 890ddd
#define TCG_FUNCTION_TYPES_H
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "traits.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <functional></functional>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \file     function_types.h
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  \brief    This file contains some template class types useful to convert
Shinya Kitaoka 120a6e
  functions
Shinya Kitaoka 120a6e
            into functors  at compile-time <\I>, with minimal memory
Shinya Kitaoka 120a6e
  overhead.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Function Objects  definition
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename f="" func="" func,=""></typename>
Toshihiro Shimizu 890ddd
struct function;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (*f)()="" ret="" ret,=""></typename>
Toshihiro Shimizu 890ddd
struct function<ret (*)(),="" f=""> : public std::unary_function<void, ret=""> {</void,></ret>
Shinya Kitaoka 120a6e
  Ret operator()() const { return f(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (*f)(arg)="" arg,="" ret="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function<ret (*)(arg),="" f=""> : public std::unary_function<arg, ret=""> {</arg,></ret>
Shinya Kitaoka 120a6e
  Ret operator()(Arg arg) const { return f(arg); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (*f)(arg1,="" arg1,="" arg2)="" arg2,="" ret="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function<ret (*)(arg1,="" arg2),="" f=""></ret>
Shinya Kitaoka 120a6e
    : public std::binary_function<arg1, arg2,="" ret=""> {</arg1,>
Shinya Kitaoka 120a6e
  Ret operator()(Arg1 arg1, Arg2 arg2) const { return f(arg1, arg2); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Member Function Objects  definition
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (c::*f)()="" c,="" ret="" ret,="" typename=""></typename>
Toshihiro Shimizu 890ddd
struct function<ret (c::*)(),="" f=""> : public std::unary_function<c &,="" ret=""> {</c></ret>
Shinya Kitaoka 120a6e
  Ret operator()(C &c) const { return (c.*f)(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (c::*f)()="" c,="" const="" ret="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function<ret (c::*)()="" const,="" f=""></ret>
Shinya Kitaoka 120a6e
    : public std::unary_function<const &,="" c="" ret=""> {</const>
Shinya Kitaoka 120a6e
  Ret operator()(const C &c) const { return (c.*f)(); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (c::*f)(arg)="" arg,="" c,="" ret="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function<ret (c::*)(arg),="" f=""></ret>
Shinya Kitaoka 120a6e
    : public std::binary_function<c &,="" arg,="" ret=""> {</c>
Shinya Kitaoka 120a6e
  Ret operator()(C &c, Arg arg) const { return (c.*f)(arg); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename (c::*f)(arg)="" arg,="" c,="" const="" ret="" ret,="" typename=""></typename>
Shinya Kitaoka 120a6e
struct function<ret (c::*)(arg)="" const,="" f=""></ret>
Shinya Kitaoka 120a6e
    : public std::binary_function<const &,="" arg,="" c="" ret=""> {</const>
Shinya Kitaoka 120a6e
  Ret operator()(const C &c, Arg arg) const { return (c.*f)(arg); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
//    Binder functors
Toshihiro Shimizu 890ddd
//************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Binary function object binder generalizing \p std::binder1st with
Toshihiro Shimizu 890ddd
            an explicitly specifiable bound type.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \note     Unlike std::binder1st, this binder accepts functors whose arguments
Toshihiro Shimizu 890ddd
            are reference types.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \sa       Helper function tcg::bind1st().
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \remark   This class currently adds an additional arguments copy.
Toshihiro Shimizu 890ddd
            Be warned of this when using heavyweight argument types.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class arg="typename" func,="" function_traits<func="" typename="">::arg1_type></class>
Shinya Kitaoka 120a6e
class binder1st
Shinya Kitaoka 120a6e
    : public std::unary_function<
Shinya Kitaoka 120a6e
          typename function_traits<func>::arg2_type,  // Forward function types</func>
Shinya Kitaoka 120a6e
          typename function_traits<func>::ret_type>   //</func>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  binder1st(const Func &func, Arg arg1) : m_func(func), m_arg1(arg1) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typename function_traits<func>::ret_type operator()(</func>
Shinya Kitaoka 120a6e
      typename function_traits<func>::arg2_type arg2)</func>
Shinya Kitaoka 120a6e
      const  // NOTE: Double copy
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return m_func(m_arg1, arg2);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  Func m_func;
Shinya Kitaoka 120a6e
  Arg m_arg1;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class arg="typename" func,="" function_traits<func="" typename="">::arg2_type></class>
Shinya Kitaoka 120a6e
class binder2nd
Shinya Kitaoka 120a6e
    : public std::unary_function<typename function_traits<func="">::arg1_type,</typename>
Shinya Kitaoka 120a6e
                                 typename function_traits<func>::ret_type> {</func>
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  binder2nd(const Func &func, Arg arg2) : m_func(func), m_arg2(arg2) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  typename function_traits<func>::ret_type operator()(</func>
Shinya Kitaoka 120a6e
      typename function_traits<func>::arg1_type arg1) const {</func>
Shinya Kitaoka 120a6e
    return m_func(arg1, m_arg2);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  Func m_func;
Shinya Kitaoka 120a6e
  Arg m_arg2;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  \brief    Helper function for the creation of binder objects with automatic
Toshihiro Shimizu 890ddd
            type deduction.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \warning  Unlike std::bind1st, the bound argument type is the one declared
Toshihiro Shimizu 890ddd
            by the function object. This is typically a commodity, but
Toshihiro Shimizu 890ddd
            be aware of the subtle implications:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
              \li Only parameters copied by value result in a copied
Toshihiro Shimizu 890ddd
                  bound argument.
Toshihiro Shimizu 890ddd
              \li Avoid temporaries as bound reference arguments.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \sa       Class tcg::binder1st.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" func,="" typename=""></typename>
Shinya Kitaoka 120a6e
inline binder1st<func> bind1st(const Func &func, const Arg &arg1) {</func>
Shinya Kitaoka 120a6e
  return binder1st<func>(func, arg1);</func>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" func,="" typename=""></typename>
Shinya Kitaoka 120a6e
inline binder1st<func> bind1st(const Func &func, Arg &arg1) {</func>
Shinya Kitaoka 120a6e
  return binder1st<func>(func, arg1);</func>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" func,="" typename=""></typename>
Shinya Kitaoka 120a6e
inline binder2nd<func> bind2nd(const Func &func, const Arg &arg2) {</func>
Shinya Kitaoka 120a6e
  return binder2nd<func>(func, arg2);</func>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename arg="" func,="" typename=""></typename>
Shinya Kitaoka 120a6e
inline binder2nd<func> bind2nd(const Func &func, Arg &arg2) {</func>
Shinya Kitaoka 120a6e
  return binder2nd<func>(func, arg2);</func>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace tcg
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_FUNCTION_TYPES_H