Commit 3c235000 by Douglas Gregor Committed by Doug Gregor

functional (_Has_result_type): Cleanup.

2005-03-02  Douglas Gregor  <doug.gregor@gmail.com>

        * include/tr1/functional (_Has_result_type): Cleanup.
        (_Result_of_impl): Handle member data pointers correctly.
        (reference_wrapper): Support invocation.
        Move repetition code into new file include/tr1/repeat.h.
        * include/tr1/functional_iterate.h (reference_wrapper): Support
        invocation.  Cleanup long lines.
        * include/tr1/ref_wrap_iterate.h (reference_wrapper): Declare
        invocation operators.
        * include/tr1/repeat.h: Code repetition header.
        * include/Makefile.am: Add ref_wrap_iterate.h, repeat.h
        * include/Makefile.in: Add ref_wrap_iterate.h, repeat.h
        * testsuite/tr1/3_function_objects/reference_wrapper/invoke.cc:
        New test of reference_wrapper invocation.
        * testsuite/tr1/3_function_objects/reference_wrapper/typedefs.cc:
        New test of reference_wrapper typedefs and base classes.
        * testsuite/tr1/3_function_objects/result_of.cc: Trivial cleanup
        (e-mail address).

2005-03-02  Douglas Gregor  <doug.gregor@gmail.com>

        * include/tr1/function (result_of): New class template.
        * include/tr1/functional/iterator.h: Implementation of TR1
        result_of.
        * testsuite/tr1/3_function_objects/result_of.cc: New test

From-SVN: r95778
parent 2563c224
2005-03-02 Douglas Gregor <doug.gregor@gmail.com>
* include/tr1/functional (_Has_result_type): Cleanup.
(_Result_of_impl): Handle member data pointers correctly.
(reference_wrapper): Support invocation.
Move repetition code into new file include/tr1/repeat.h.
* include/tr1/functional_iterate.h (reference_wrapper): Support
invocation. Cleanup long lines.
* include/tr1/ref_wrap_iterate.h (reference_wrapper): Declare
invocation operators.
* include/tr1/repeat.h: Code repetition header.
* include/Makefile.am: Add ref_wrap_iterate.h, repeat.h
* include/Makefile.in: Add ref_wrap_iterate.h, repeat.h
* testsuite/tr1/3_function_objects/reference_wrapper/invoke.cc:
New test of reference_wrapper invocation.
* testsuite/tr1/3_function_objects/reference_wrapper/typedefs.cc:
New test of reference_wrapper typedefs and base classes.
* testsuite/tr1/3_function_objects/result_of.cc: Trivial cleanup
(e-mail address).
2005-03-02 Douglas Gregor <doug.gregor@gmail.com>
* include/tr1/function (result_of): New class template.
* include/tr1/functional/iterator.h: Implementation of TR1
result_of.
* testsuite/tr1/3_function_objects/result_of.cc: New test
2005-03-01 Vladimir Merzliakov <wanderer@rsu.ru>
* testsuite/26_numerics/cmath/c99_classification_macros_c.cc: Tweak.
......
......@@ -231,6 +231,8 @@ tr1_headers = \
${tr1_srcdir}/functional \
${tr1_srcdir}/functional_iterate.h \
${tr1_srcdir}/memory \
${tr1_srcdir}/ref_wrap_iterate.h \
${tr1_srcdir}/repeat.h \
${tr1_srcdir}/tuple \
${tr1_srcdir}/utility \
${tr1_srcdir}/type_traits \
......
......@@ -447,6 +447,8 @@ tr1_headers = \
${tr1_srcdir}/functional \
${tr1_srcdir}/functional_iterate.h \
${tr1_srcdir}/memory \
${tr1_srcdir}/ref_wrap_iterate.h \
${tr1_srcdir}/repeat.h \
${tr1_srcdir}/tuple \
${tr1_srcdir}/utility \
${tr1_srcdir}/type_traits \
......
// TR1 functional -*- C++ -*-
// Copyright (C) 2005 Free Software Foundation, Inc.
// Writtten by Douglas Gregor <dgregor@cs.indiana.edu>
// Written by Douglas Gregor <doug.gregor -at- gmail.com>
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
......@@ -33,6 +33,145 @@
* You should not attempt to use it directly.
*/
template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
struct _Weak_result_type_impl<_Res(_GLIBCXX_TEMPLATE_ARGS)>
{
typedef _Res result_type;
};
template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
struct _Weak_result_type_impl<_Res (&)(_GLIBCXX_TEMPLATE_ARGS)>
{
typedef _Res result_type;
};
template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
struct _Weak_result_type_impl<_Res (*)(_GLIBCXX_TEMPLATE_ARGS)>
{
typedef _Res result_type;
};
#if _GLIBCXX_NUM_ARGS > 0
template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
_GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
struct _Weak_result_type_impl<
_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED)>
{
typedef _Res result_type;
};
template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
_GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
struct _Weak_result_type_impl<
_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const>
{
typedef _Res result_type;
};
template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
_GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
struct _Weak_result_type_impl<
_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) volatile>
{
typedef _Res result_type;
};
template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
_GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
struct _Weak_result_type_impl<
_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
{
typedef _Res result_type;
};
#endif
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
class result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>
: public _Result_of_impl<
_Has_result_type<_Weak_result_type<_Functor> >::value,
_Functor(_GLIBCXX_TEMPLATE_ARGS)>
{ };
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
struct _Result_of_impl<true, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
{
typedef typename _Weak_result_type<_Functor>::result_type type;
};
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
struct _Result_of_impl<false, _Functor(_GLIBCXX_TEMPLATE_ARGS)>
{
#if _GLIBCXX_NUM_ARGS > 0
typedef typename _Functor
::template result<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type type;
#else
typedef void type;
#endif
};
/**
* @if maint
* Invoke a function object, which may be either a member pointer or a
* function object. The first parameter will tell which.
* @endif
*/
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
inline
typename __enable_if<
typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type,
(!is_member_pointer<_Functor>::value
&& !is_function<_Functor>::value
&& !is_function<typename remove_pointer<_Functor>::type>::value)
>::__type
__invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
{
return __f(_GLIBCXX_ARGS);
}
#if _GLIBCXX_NUM_ARGS > 0
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
inline
typename __enable_if<
typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type,
(is_member_pointer<_Functor>::value
&& !is_function<_Functor>::value
&& !is_function<typename remove_pointer<_Functor>::type>::value)
>::__type
__invoke(_Functor& __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
{
return mem_fn(__f)(_GLIBCXX_ARGS);
}
#endif
// To pick up function references (that will become function pointers)
template<typename _Functor _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
inline
typename __enable_if<
typename result_of<_Functor(_GLIBCXX_TEMPLATE_ARGS)>::type,
(is_pointer<_Functor>::value
&& is_function<typename remove_pointer<_Functor>::type>::value)
>::__type
__invoke(_Functor __f _GLIBCXX_COMMA _GLIBCXX_REF_PARAMS)
{
return __f(_GLIBCXX_ARGS);
}
/**
* @if maint
* Implementation of reference_wrapper::operator()
* @endif
*/
#if _GLIBCXX_NUM_ARGS > 0
template<typename _Tp>
template<_GLIBCXX_TEMPLATE_PARAMS>
typename result_of<
typename reference_wrapper<_Tp>::_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type
reference_wrapper<_Tp>::operator()(_GLIBCXX_REF_PARAMS) const
{
return __invoke(get(), _GLIBCXX_ARGS);
}
#endif
#if _GLIBCXX_NUM_ARGS > 0
template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
_GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
......@@ -197,7 +336,7 @@ template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
template<typename _Res, typename _Class _GLIBCXX_COMMA_SHIFTED
_GLIBCXX_TEMPLATE_PARAMS_SHIFTED>
class _Mem_fn<_Res (_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
class _Mem_fn<_Res(_Class::*)(_GLIBCXX_TEMPLATE_ARGS_SHIFTED) const volatile>
#if _GLIBCXX_NUM_ARGS == 1
: public unary_function<const volatile _Class*, _Res>
#elif _GLIBCXX_NUM_ARGS == 2
......@@ -600,7 +739,8 @@ class function<_Res(_GLIBCXX_TEMPLATE_ARGS)>
template<typename _Function>
void operator!=(const function<_Function>&) const;
typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA _GLIBCXX_PARAMS);
typedef _Res (*_Invoker_type)(const _Any_data& _GLIBCXX_COMMA
_GLIBCXX_PARAMS);
_Invoker_type _M_invoker;
};
......@@ -632,7 +772,8 @@ template<typename _Functor>
}
template<typename _Res _GLIBCXX_COMMA _GLIBCXX_TEMPLATE_PARAMS>
_Res function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
_Res
function<_Res(_GLIBCXX_TEMPLATE_ARGS)>::operator()(_GLIBCXX_PARAMS) const
{
if (_M_empty())
{
......
// TR1 reference_wrapper -*- C++ -*-
// Copyright (C) 2005 Free Software Foundation, Inc.
// Written by Douglas Gregor <doug.gregor -at- gmail.com>
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file ref_wrap_iterate.h
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
#if _GLIBCXX_NUM_ARGS > 0
template<_GLIBCXX_TEMPLATE_PARAMS>
typename result_of<_M_func_type(_GLIBCXX_TEMPLATE_ARGS)>::type
operator()(_GLIBCXX_REF_PARAMS) const;
#else
typename result_of<_M_func_type()>::type
operator()() const
{ return (*get())(); }
#endif
// 2005-02-27 Douglas Gregor <doug.gregor -at- gmail.com>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 2.1 reference wrappers
#include <tr1/functional>
#include <tr1/type_traits>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>
using namespace __gnu_test;
bool test __attribute__((unused)) = true;
struct X
{
typedef int result_type;
X() : bar(17) {}
int foo(float x) { return truncate_float(x); }
int foo_c(float x) const { return truncate_float(x); }
int foo_v(float x) volatile { return truncate_float(x); }
int foo_cv(float x) const volatile { return truncate_float(x); }
int operator()(float x)
{
return foo(x) + 1;
}
int operator()(float x) const
{
return foo_c(x) + 2;
}
int bar;
private:
X(const X&);
X& operator=(const X&);
};
void test01()
{
using std::tr1::ref;
using std::tr1::cref;
::X x;
::X* xp = &x;
int (::X::* p_foo)(float) = &::X::foo;
int (::X::* p_foo_c)(float) const = &::X::foo_c;
int (::X::* p_foo_v)(float) volatile = &::X::foo_v;
int (::X::* p_foo_cv)(float) const volatile = &::X::foo_cv;
int ::X::* p_bar = &::X::bar;
const float pi = 3.14;
// Functions
VERIFY(ref(truncate_float)(pi) == 3);
// Function pointers
VERIFY(cref(&truncate_float)(pi) == 3);
// Member function pointers
VERIFY(ref(p_foo)(x, pi) == 3);
VERIFY(ref(p_foo)(xp, pi) == 3);
VERIFY(ref(p_foo_c)(x, pi) == 3);
VERIFY(ref(p_foo_c)(xp, pi) == 3);
VERIFY(ref(p_foo_v)(x, pi) == 3);
VERIFY(ref(p_foo_v)(xp, pi) == 3);
VERIFY(ref(p_foo_cv)(x, pi) == 3);
VERIFY(ref(p_foo_cv)(xp, pi) == 3);
// Member data pointers
VERIFY(ref(p_bar)(x) == 17);
VERIFY(ref(p_bar)(xp) == 17);
// Function objects
VERIFY(ref(x)(pi) == 4);
VERIFY(cref(x)(pi) == 5);
}
int main()
{
test01();
return 0;
}
// 2005-02-27 Douglas Gregor <doug.gregor -at- gmail.com>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 2.1 reference wrappers
#include <tr1/functional>
#include <tr1/type_traits>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>
using namespace __gnu_test;
struct X {};
struct int_result_type { typedef int result_type; };
struct derives_unary : std::unary_function<int, int> {};
struct derives_binary : std::binary_function<int, float, int> {};
struct derives_unary_binary
: std::unary_function<int, int>,
std::binary_function<int, float, int>
{
typedef int result_type;
};
void test01()
{
bool test __attribute__((unused)) = true;
using std::tr1::reference_wrapper;
using std::tr1::is_same;
using std::tr1::is_convertible;
using std::unary_function;
using std::binary_function;
// Check result_type typedef
VERIFY((is_same<reference_wrapper<int_result_type>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<derives_unary>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<derives_binary>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<derives_unary_binary>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<int(void)>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<int(*)(void)>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<int (::X::*)()>::result_type, int>::value));
VERIFY((is_same<reference_wrapper<int (::X::*)(float)>::result_type, int>::value));
// Check derivation from unary_function
VERIFY((is_convertible<reference_wrapper<derives_unary>*, unary_function<int, int>*>::value));
VERIFY((is_convertible<reference_wrapper<derives_unary_binary>*, unary_function<int, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int(int)>*, unary_function<int, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int(*)(int)>*, unary_function<int, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)()>*, unary_function< ::X*, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)() const>*, unary_function<const ::X*, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)() volatile>*, unary_function<volatile ::X*, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)() const volatile>*, unary_function<const volatile ::X*, int>*>::value));
// Check derivation from binary_function
VERIFY((is_convertible<reference_wrapper<derives_binary>*, binary_function<int, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<derives_unary_binary>*, binary_function<int, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int(int, float)>*, binary_function<int, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int(*)(int, float)>*, binary_function<int, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)(float)>*, binary_function< ::X*, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)(float) const>*, binary_function<const ::X*, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)(float) volatile>*, binary_function<volatile ::X*, float, int>*>::value));
VERIFY((is_convertible<reference_wrapper<int (::X::*)(float) const volatile>*, binary_function<const volatile ::X*, float, int>*>::value));
}
int main()
{
test01();
return 0;
}
// 2005-01-26 Douglas Gregor <doug.gregor -at- gmail.com>
//
// Copyright (C) 2005 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 3.4 function return types
#include <tr1/functional>
#include <tr1/type_traits>
#include <testsuite_hooks.h>
#include <testsuite_tr1.h>
class X {};
struct int_result_type { typedef int result_type; };
struct int_result_of
{
template<typename F> struct result { typedef int type; };
};
struct int_result_type_and_float_result_of
{
typedef int result_type;
template<typename F> struct result { typedef float type; };
};
void test01()
{
bool test __attribute__((unused)) = true;
using std::tr1::result_of;
using std::tr1::is_same;
using namespace __gnu_test;
typedef int (*func_ptr)(float, double);
typedef int (&func_ref)(float, double);
typedef int (::X::*mem_func_ptr)(float);
typedef int (::X::*mem_func_ptr_c)(float) const;
typedef int (::X::*mem_func_ptr_v)(float) volatile;
typedef int (::X::*mem_func_ptr_cv)(float) const volatile;
VERIFY((is_same<result_of<int_result_type(float)>::type, int>::value));
VERIFY((is_same<result_of<int_result_of(double)>::type, int>::value));
VERIFY((is_same<result_of<int_result_of(void)>::type, void>::value));
VERIFY((is_same<result_of<const int_result_of(double)>::type, int>::value));
VERIFY((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
VERIFY((is_same<result_of<int_result_type_and_float_result_of(char)>::type, int>::value));
VERIFY((is_same<result_of<func_ptr(char, float)>::type, int>::value));
VERIFY((is_same<result_of<func_ref(char, float)>::type, int>::value));
VERIFY((is_same<result_of<mem_func_ptr(::X,char)>::type, int>::value));
VERIFY((is_same<result_of<mem_func_ptr_c(::X,char)>::type, int>::value));
VERIFY((is_same<result_of<mem_func_ptr_v(::X,char)>::type, int>::value));
VERIFY((is_same<result_of<mem_func_ptr_cv(::X,char)>::type, int>::value));
}
int main()
{
test01();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment