forked from boostorg/function
Compare commits
9 Commits
boost-1.27
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
0dcec9ffb9 | |||
4d635501ab | |||
d1f21800ac | |||
092cb0d706 | |||
57ee7e962a | |||
48943fec83 | |||
a0b89d0a30 | |||
82226cb9d6 | |||
28984e4f23 |
@ -96,7 +96,7 @@ object. This is often referred to as "argument binding", and is beyond the scope
|
||||
|
||||
f(5); // Call x.foo(5)</pre></li>
|
||||
|
||||
<li><a href="http://lambda.cs.utu.fi/">The Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. Note that it is not a Boost library.</li>
|
||||
<li><a href="../../lambda/doc/index.html">The Boost.Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. </li>
|
||||
</ul>
|
||||
|
||||
<h3>References to Functions</h3>
|
||||
@ -199,7 +199,7 @@ boost::function2<float, int, int, SynchronizedPolicy, SynchronizedMixin> f
|
||||
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
||||
<!-- Created: Fri Jul 13 12:47:11 EDT 2001 -->
|
||||
<!-- hhmts start -->
|
||||
Last modified: Fri Dec 14 19:58:14 EST 2001
|
||||
Last modified: Mon May 13 08:31:23 EDT 2002
|
||||
<!-- hhmts end -->
|
||||
</body>
|
||||
</html>
|
||||
|
@ -53,9 +53,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -78,9 +78,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -103,9 +103,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -128,9 +128,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -153,9 +153,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -178,9 +178,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -204,9 +204,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -230,9 +230,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -256,9 +256,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -282,9 +282,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
@ -308,9 +308,9 @@ namespace boost {
|
||||
typename T8,
|
||||
typename T9,
|
||||
typename T10,
|
||||
typename Policy = empty_function_policy,
|
||||
typename Mixin = empty_function_mixin,
|
||||
typename Allocator = std::allocator<function_base>
|
||||
typename Policy,
|
||||
typename Mixin,
|
||||
typename Allocator
|
||||
>
|
||||
struct params
|
||||
{
|
||||
|
@ -34,8 +34,10 @@
|
||||
namespace boost {
|
||||
namespace detail {
|
||||
namespace function {
|
||||
template<bool> struct truth {};
|
||||
|
||||
/*
|
||||
* The IF implementation is temporary code. When a Boost metaprogramming
|
||||
* The ct_if implementation is temporary code. When a Boost metaprogramming
|
||||
* library is introduced, Boost.Function will use it instead.
|
||||
*/
|
||||
namespace intimate {
|
||||
@ -71,7 +73,7 @@ namespace boost {
|
||||
} // end namespace intimate
|
||||
|
||||
template<bool Condition, typename Then, typename Else>
|
||||
struct IF
|
||||
struct ct_if
|
||||
{
|
||||
typedef typename intimate::Selector<Condition>::type select;
|
||||
typedef typename select::template Result<Then,Else>::type type;
|
||||
@ -135,20 +137,20 @@ namespace boost {
|
||||
template<typename F>
|
||||
class get_function_tag
|
||||
{
|
||||
typedef typename IF<(is_pointer<F>::value),
|
||||
typedef typename ct_if<(is_pointer<F>::value),
|
||||
function_ptr_tag,
|
||||
function_obj_tag>::type ptr_or_obj_tag;
|
||||
|
||||
typedef typename IF<(is_member_pointer<F>::value),
|
||||
typedef typename ct_if<(is_member_pointer<F>::value),
|
||||
member_ptr_tag,
|
||||
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
|
||||
|
||||
typedef typename IF<(is_reference_wrapper<F>::value),
|
||||
typedef typename ct_if<(is_reference_wrapper<F>::value),
|
||||
function_obj_ref_tag,
|
||||
ptr_or_obj_or_mem_tag>::type or_ref_tag;
|
||||
|
||||
public:
|
||||
typedef typename IF<(is_stateless<F>::value),
|
||||
typedef typename ct_if<(is_stateless<F>::value),
|
||||
stateless_function_obj_tag,
|
||||
or_ref_tag>::type type;
|
||||
};
|
||||
@ -156,7 +158,7 @@ namespace boost {
|
||||
// The trivial manager does nothing but return the same pointer (if we
|
||||
// are cloning) or return the null pointer (if we are deleting).
|
||||
inline any_pointer trivial_manager(any_pointer f,
|
||||
functor_manager_operation_type op)
|
||||
functor_manager_operation_type op)
|
||||
{
|
||||
if (op == clone_functor_tag)
|
||||
return f;
|
||||
@ -176,7 +178,8 @@ namespace boost {
|
||||
|
||||
// For function pointers, the manager is trivial
|
||||
static inline any_pointer
|
||||
manager(any_pointer function_ptr, functor_manager_operation_type op,
|
||||
manager(any_pointer function_ptr,
|
||||
functor_manager_operation_type op,
|
||||
function_ptr_tag)
|
||||
{
|
||||
if (op == clone_functor_tag)
|
||||
@ -307,6 +310,10 @@ namespace boost {
|
||||
detail::function::functor_manager_operation_type);
|
||||
detail::function::any_pointer functor;
|
||||
|
||||
#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
|
||||
// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
|
||||
operator bool () const { return !this->empty(); }
|
||||
#else
|
||||
private:
|
||||
struct dummy {
|
||||
void nonnull() {};
|
||||
@ -320,6 +327,7 @@ namespace boost {
|
||||
|
||||
safe_bool operator!() const
|
||||
{ return (this->empty())? &dummy::nonnull : 0; }
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Poison comparison between Boost.Function objects (because it is
|
||||
@ -333,92 +341,14 @@ namespace boost {
|
||||
|
||||
namespace detail {
|
||||
namespace function {
|
||||
/**
|
||||
* Determine if the given target is empty.
|
||||
*/
|
||||
|
||||
// Fallback - assume target is not empty
|
||||
inline bool has_empty_target(...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the target is a 'function', query the empty() method
|
||||
inline bool has_empty_target(const function_base* af)
|
||||
{
|
||||
return af->empty();
|
||||
inline bool has_empty_target(const function_base* f)
|
||||
{
|
||||
return f->empty();
|
||||
}
|
||||
|
||||
// If the target is a 'function', query the empty() method
|
||||
inline bool has_empty_target(const function_base& af)
|
||||
{
|
||||
return af.empty();
|
||||
}
|
||||
|
||||
// A function pointer is empty if it is null
|
||||
template<typename R>
|
||||
inline bool has_empty_target(R (*f)())
|
||||
inline bool has_empty_target(...)
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1>
|
||||
inline bool has_empty_target(R (*f)(T1))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2>
|
||||
inline bool has_empty_target(R (*f)(T1, T2))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3, typename T4>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7, typename T8>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8))
|
||||
{
|
||||
return f == 0;
|
||||
}
|
||||
|
||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
||||
typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9))
|
||||
{
|
||||
return f == 0;
|
||||
return false;
|
||||
}
|
||||
} // end namespace function
|
||||
} // end namespace detail
|
||||
@ -430,14 +360,18 @@ namespace boost {
|
||||
inline void postcall(const function_base*) {}
|
||||
};
|
||||
|
||||
// The default function mixin does nothing. The assignment and copy-construction operators
|
||||
// are all defined because MSVC defines broken versions.
|
||||
struct empty_function_mixin {
|
||||
empty_function_mixin() {};
|
||||
empty_function_mixin(const empty_function_mixin&) {};
|
||||
// The default function mixin does nothing. The assignment and
|
||||
// copy-construction operators are all defined because MSVC defines broken
|
||||
// versions.
|
||||
struct empty_function_mixin
|
||||
{
|
||||
empty_function_mixin() {}
|
||||
empty_function_mixin(const empty_function_mixin&) {}
|
||||
|
||||
empty_function_mixin& operator=(const empty_function_mixin&)
|
||||
{return *this; }
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,6 @@
|
||||
|
||||
// Class names used in this version of the code
|
||||
#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
|
||||
#define BOOST_FUNCTION_BASE BOOST_JOIN(function_base,BOOST_FUNCTION_NUM_ARGS)
|
||||
#define BOOST_FUNCTION_FUNCTION_INVOKER \
|
||||
BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
|
||||
@ -168,7 +167,7 @@ namespace boost {
|
||||
>
|
||||
struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
|
||||
{
|
||||
typedef typename IF<(is_void<R>::value),
|
||||
typedef typename ct_if<(is_void<R>::value),
|
||||
BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
|
||||
FunctionPtr,
|
||||
R BOOST_FUNCTION_COMMA
|
||||
@ -189,7 +188,7 @@ namespace boost {
|
||||
>
|
||||
struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
||||
{
|
||||
typedef typename IF<(is_void<R>::value),
|
||||
typedef typename ct_if<(is_void<R>::value),
|
||||
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
|
||||
FunctionObj,
|
||||
R BOOST_FUNCTION_COMMA
|
||||
@ -210,7 +209,7 @@ namespace boost {
|
||||
>
|
||||
struct BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
|
||||
{
|
||||
typedef typename IF<(is_void<R>::value),
|
||||
typedef typename ct_if<(is_void<R>::value),
|
||||
BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER<
|
||||
FunctionObj,
|
||||
R BOOST_FUNCTION_COMMA
|
||||
@ -361,9 +360,12 @@ namespace boost {
|
||||
// Clear out a target, if there is one
|
||||
void clear()
|
||||
{
|
||||
if (function_base::manager)
|
||||
function_base::functor = function_base::manager(function_base::functor, detail::function::destroy_functor_tag);
|
||||
|
||||
if (function_base::manager) {
|
||||
function_base::functor =
|
||||
function_base::manager(function_base::functor,
|
||||
detail::function::destroy_functor_tag);
|
||||
}
|
||||
|
||||
function_base::manager = 0;
|
||||
invoker = 0;
|
||||
}
|
||||
@ -374,7 +376,8 @@ namespace boost {
|
||||
if (!f.empty()) {
|
||||
invoker = f.invoker;
|
||||
function_base::manager = f.manager;
|
||||
function_base::functor = f.manager(f.functor, detail::function::clone_functor_tag);
|
||||
function_base::functor =
|
||||
f.manager(f.functor, detail::function::clone_functor_tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -399,9 +402,10 @@ namespace boost {
|
||||
invoker_type;
|
||||
|
||||
invoker = &invoker_type::invoke;
|
||||
function_base::manager = &detail::function::functor_manager<FunctionPtr,
|
||||
Allocator>::manage;
|
||||
function_base::functor = function_base::manager(detail::function::any_pointer(
|
||||
function_base::manager =
|
||||
&detail::function::functor_manager<FunctionPtr, Allocator>::manage;
|
||||
function_base::functor =
|
||||
function_base::manager(detail::function::any_pointer(
|
||||
// should be a reinterpret cast, but some compilers
|
||||
// insist on giving cv-qualifiers to free functions
|
||||
(void (*)())(f)
|
||||
@ -421,7 +425,7 @@ namespace boost {
|
||||
template<typename FunctionObj>
|
||||
void assign_to(FunctionObj f, detail::function::function_obj_tag)
|
||||
{
|
||||
if (!detail::function::has_empty_target(&f)) {
|
||||
if (!detail::function::has_empty_target(addressof(f))) {
|
||||
typedef
|
||||
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||
FunctionObj,
|
||||
@ -431,11 +435,23 @@ namespace boost {
|
||||
invoker_type;
|
||||
|
||||
invoker = &invoker_type::invoke;
|
||||
function_base::manager = &detail::function::functor_manager<FunctionObj,
|
||||
Allocator>::manage;
|
||||
function_base::manager = &detail::function::functor_manager<
|
||||
FunctionObj, Allocator>::manage;
|
||||
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||
typedef typename Allocator::template rebind<FunctionObj>::other
|
||||
allocator_type;
|
||||
typedef typename allocator_type::pointer pointer_type;
|
||||
allocator_type allocator;
|
||||
pointer_type copy = allocator.allocate(1);
|
||||
allocator.construct(copy, f);
|
||||
|
||||
// Get back to the original pointer type
|
||||
FunctionObj* new_f = static_cast<FunctionObj*>(copy);
|
||||
#else
|
||||
FunctionObj* new_f = new FunctionObj(f);
|
||||
#endif // BOOST_NO_STD_ALLOCATOR
|
||||
function_base::functor =
|
||||
function_base::manager(detail::function::any_pointer(const_cast<FunctionObj*>(&f)),
|
||||
detail::function::clone_functor_tag);
|
||||
detail::function::any_pointer(static_cast<void*>(new_f));
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +459,7 @@ namespace boost {
|
||||
void assign_to(const reference_wrapper<FunctionObj>& f,
|
||||
detail::function::function_obj_ref_tag)
|
||||
{
|
||||
if (!detail::function::has_empty_target(&f.get())) {
|
||||
if (!detail::function::has_empty_target(f.get_pointer())) {
|
||||
typedef
|
||||
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||
FunctionObj,
|
||||
@ -455,9 +471,10 @@ namespace boost {
|
||||
invoker = &invoker_type::invoke;
|
||||
function_base::manager = &detail::function::trivial_manager;
|
||||
function_base::functor =
|
||||
function_base::manager(detail::function::any_pointer(
|
||||
const_cast<FunctionObj*>(&f.get())),
|
||||
detail::function::clone_functor_tag);
|
||||
function_base::manager(
|
||||
detail::function::any_pointer(
|
||||
const_cast<FunctionObj*>(f.get_pointer())),
|
||||
detail::function::clone_functor_tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,8 +526,6 @@ namespace boost {
|
||||
#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
||||
#undef BOOST_FUNCTION_COMMA
|
||||
#undef BOOST_FUNCTION_FUNCTION
|
||||
#undef BOOST_FUNCTION_BASE
|
||||
#undef BOOST_FUNCTION_INVOKER_BASE
|
||||
#undef BOOST_FUNCTION_FUNCTION_INVOKER
|
||||
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
|
||||
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
|
||||
@ -521,4 +536,3 @@ namespace boost {
|
||||
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
||||
#undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
|
||||
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
|
||||
|
||||
|
Reference in New Issue
Block a user