1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
/*
* Copyright 2003 - 2016, The libsigc++ Development Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SIGC_ADAPTORS_RETYPE_H
#define SIGC_ADAPTORS_RETYPE_H
#include <sigc++/adaptors/adapts.h>
#include <sigc++/functors/ptr_fun.h>
#include <sigc++/functors/mem_fun.h>
#include <sigc++/functors/slot.h>
namespace sigc
{
/** @defgroup retype retype(), retype_return()
* sigc::retype() alters a sigc::pointer_functor, a sigc::mem_functor or
* a @ref sigc::slot<T_return(T_arg...)> "sigc::slot"
* in that it makes C-style casts to the functor's parameter types
* of all parameters passed through operator()().
*
* Use this adaptor for inline conversion between numeric or other simple types.
* @par Example:
* @code
* void foo(int);
* sigc::retype(sigc::ptr_fun(&foo))(5.7F); // calls foo(5)
* @endcode
*
* The functor that sigc::retype() returns can be passed directly into
* @ref sigc::signal_with_accumulator::connect() "sigc::signal::connect()".
*
* @par Example:
* @code
* sigc::signal<void(float)> some_signal;
* void foo(int);
* some_signal.connect(sigc::retype(sigc::ptr_fun(&foo)));
* @endcode
*
* This adaptor builds an exception in that it only works on sigc::pointer_functor,
* sigc::mem_functor and @ref sigc::slot<T_return(T_arg...)> "sigc::slot"
* because it needs sophisticated information about
* the parameter types that cannot be deduced from arbitrary functor types.
*
* sigc::retype_return() alters the return type of an arbitrary functor.
* Like in sigc::retype() a C-style cast is performed. Usage sigc::retype_return() is
* not restricted to libsigc++ functor types but you need to
* specify the new return type as a template parameter.
*
* @par Example:
* @code
* float foo();
* std::cout << sigc::retype_return<int>(&foo)(); // converts foo's return value to an integer
* @endcode
*
* @ingroup adaptors
*/
/** Adaptor that performs C-style casts on the parameters passed on to the functor.
* Use the convenience function sigc::retype() to create an instance of retype_functor.
*
* The following template arguments are used:
* - @e T_functor Type of the functor to wrap.
* - @e T_type Types of @e T_functor's arguments.
*
* @ingroup retype
*/
template<typename T_functor, typename... T_type>
struct retype_functor : public adapts<T_functor>
{
template<typename... T_arg>
decltype(auto) operator()(T_arg... a)
{
return std::invoke(this->functor_, static_cast<T_type>(a)...);
}
/** Constructs a retype_functor object that performs C-style casts on the parameters passed on to
* the functor.
* @param functor Functor to invoke from operator()().
*/
explicit retype_functor(type_trait_take_t<T_functor> functor) : adapts<T_functor>(functor) {}
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
// template specialization of visitor<>::do_visit_each<>(action, functor):
/** Performs a functor on each of the targets of a functor.
* The function overload for sigc::retype_functor performs a functor on the
* functor stored in the sigc::retype_functor object.
*
* @ingroup retype
*/
template<typename T_functor, typename... T_type>
struct visitor<retype_functor<T_functor, T_type...>>
{
template<typename T_action>
static void do_visit_each(const T_action& action,
const retype_functor<T_functor, T_type...>& target)
{
sigc::visit_each(action, target.functor_);
}
};
#endif // DOXYGEN_SHOULD_SKIP_THIS
// This one takes, for instance, a mem_functor or bound_mem_functor:
/** Creates an adaptor of type sigc::retype_functor which performs C-style casts on the parameters
* passed on to the functor.
*
* @param functor Functor that should be wrapped.
* @return Adaptor that executes @e functor performing C-style casts on the paramters passed on.
*
* @ingroup retype
*/
template<template<typename T_func, typename... T_arg> class T_functor,
typename T_func,
typename... T_arg>
inline decltype(auto)
retype(const T_functor<T_func, T_arg...>& functor)
{
return retype_functor<T_functor<T_func, T_arg...>, T_arg...>(functor);
}
// This one takes, for instance, a pointer_functor or slot:
/** Creates an adaptor of type sigc::retype_functor which performs C-style casts on the parameters
* passed on to the functor.
*
* @param functor Functor that should be wrapped.
* @return Adaptor that executes @e functor performing C-style casts on the paramters passed on.
*
* @ingroup retype
*/
template<template<typename T_return, typename... T_arg> class T_functor,
typename T_return,
typename... T_arg>
inline decltype(auto)
retype(const T_functor<T_return(T_arg...)>& functor)
{
return retype_functor<T_functor<T_return(T_arg...)>, T_arg...>(functor);
}
} /* namespace sigc */
#endif /* SIGC_ADAPTORS_RETYPE_H */
|