/* Copyright 2005 - 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, see .
*/
#ifndef SIGC_BOUND_ARGUMENT_H
#define SIGC_BOUND_ARGUMENT_H
#include
#include
namespace sigc
{
/** A bound_argument object stores a bound (for instance, with sigc::bind(), or
* sigc::bind_return()) argument.
*
* If Foo is a wrapped reference to a class Bar (std::reference_wrapper) then this
* object is implemented on top of a limit_reference. When the slot is
* invoked, the limit_reference::invoke() method provides the argument (a Bar&).
* When the slot is visited (e.g. visit_each<>()), we simply visit the limit_reference,
* which will visit the derived type, or a sigc::trackable base if necessary.
*
* Likewise, If Foo is a wrapped const reference to a class Bar (std::reference_wrapper)
* then this object is implemented on top of a const_limit_reference.
*
* If Foo is something else (such as an argument that is bound by value) bound_argument just
* stores a cop of that value, and both invoke() and visit() simply return it.
*
* This object is used by the bind_functor<> and bind_return_functor<> objects,
* depending on whether the argument is bound as a parameter or as a return value.
*
* The general template implementation is used for parameters that are passed by value.
* @e T_type The type of the bound argument.
*/
template
class bound_argument
{
public:
/** Constructor.
* @param arg The argument to bind.
*/
bound_argument(const T_type& arg) : visited_(arg) {}
/** Retrieve the entity to visit in visit_each().
* @return The bound argument.
*/
inline const T_type& visit() const { return visited_; }
/** Retrieve the entity to pass to the bound functor or return.
* @return The bound argument.
*/
inline T_type& invoke() { return visited_; }
private:
/** The value of the argument.
*/
T_type visited_;
};
// Template specialization:
/** bound_argument object for a bound argument that is passed by bind() or
* returned by bind_return() by reference, specialized for std::reference_wrapper<> types.
* @e T_wrapped The type of the bound argument.
*/
template
class bound_argument>
{
public:
/** Constructor.
* @param arg The argument to bind.
*/
bound_argument(const std::reference_wrapper& arg) : visited_(unwrap(arg)) {}
/** Retrieve the entity to visit in visit_each().
* @return The limited_reference to the bound argument.
*/
inline const limit_reference& visit() const { return visited_; }
/** Retrieve the entity to pass to the bound functor or return.
* @return The bound argument.
*/
inline T_wrapped& invoke() { return visited_.invoke(); }
private:
/** The limited_reference to the bound argument.
*/
limit_reference visited_;
};
/** bound_argument object for a bound argument that is passed by bind() or
* returned by bind_return() by const reference, specialized for const reference_wrapper<> types.
* - @e T_wrapped The type of the bound argument.
*/
template
class bound_argument>
{
public:
/** Constructor.
* @param arg The argument to bind.
*/
bound_argument(const std::reference_wrapper& arg) : visited_(unwrap(arg)) {}
/** Retrieve the entity to visit in visit_each().
* @return The const_limited_reference to the bound argument.
*/
inline const limit_reference& visit() const { return visited_; }
/** Retrieve the entity to pass to the bound functor or return.
* @return The bound argument.
*/
inline const T_wrapped& invoke() { return visited_.invoke(); }
private:
/** The const_limited_reference to the bound argument.
*/
limit_reference visited_;
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/** Implementation of visitor<>::do_visit_each<>() specialized for the bound_argument class.
* Call visit_each() on the entity returned by the bound_argument's visit()
* method.
* @tparam T_type The type of bound_argument.
* @tparam T_action The type of functor to invoke.
* @param action The functor to invoke.
* @param arg The visited instance.
*/
template
struct visitor>
{
template
static void do_visit_each(const T_action& action, const bound_argument& arg)
{
sigc::visit_each(action, arg.visit());
}
};
#endif // DOXYGEN_SHOULD_SKIP_THIS
} /* namespace sigc */
#endif /* SIGC_BOUND_ARGUMENT_H */