Compare commits

..

2 Commits

Author SHA1 Message Date
efabc7cfc9 This commit was manufactured by cvs2svn to create tag
'Version_1_27_0'.

[SVN r12749]
2002-02-07 13:33:59 +00:00
9b73ca6055 This commit was manufactured by cvs2svn to create branch 'RC_1_27_0'.
[SVN r12739]
2002-02-06 03:32:50 +00:00
11 changed files with 449 additions and 340 deletions

View File

@ -1,6 +1,6 @@
// Boost.Function library
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
@ -53,12 +53,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function0<R, ThreadingPolicy, Allocator> type;
typedef function0<R, Policy, Mixin, Allocator> type;
};
};
@ -77,12 +78,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function1<R, T1, ThreadingPolicy, Allocator> type;
typedef function1<R, T1, Policy, Mixin, Allocator> type;
};
};
@ -101,12 +103,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function2<R, T1, T2, ThreadingPolicy, Allocator> type;
typedef function2<R, T1, T2, Policy, Mixin, Allocator> type;
};
};
@ -125,12 +128,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function3<R, T1, T2, T3, ThreadingPolicy, Allocator> type;
typedef function3<R, T1, T2, T3, Policy, Mixin, Allocator> type;
};
};
@ -149,12 +153,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function4<R, T1, T2, T3, T4, ThreadingPolicy, Allocator> type;
typedef function4<R, T1, T2, T3, T4, Policy, Mixin, Allocator> type;
};
};
@ -173,12 +178,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function5<R, T1, T2, T3, T4, T5, ThreadingPolicy, Allocator>
typedef function5<R, T1, T2, T3, T4, T5, Policy, Mixin, Allocator>
type;
};
};
@ -198,12 +204,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function6<R, T1, T2, T3, T4, T5, T6, ThreadingPolicy, Allocator>
typedef function6<R, T1, T2, T3, T4, T5, T6, Policy, Mixin, Allocator>
type;
};
};
@ -223,12 +230,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function7<R, T1, T2, T3, T4, T5, T6, T7, ThreadingPolicy,
typedef function7<R, T1, T2, T3, T4, T5, T6, T7, Policy, Mixin,
Allocator> type;
};
};
@ -248,12 +256,13 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8, ThreadingPolicy,
typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8, Policy, Mixin,
Allocator> type;
};
};
@ -273,13 +282,14 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
ThreadingPolicy, Allocator> type;
typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, Policy,
Mixin, Allocator> type;
};
};
@ -298,13 +308,14 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy,
typename Allocator
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct params
{
typedef function10<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
ThreadingPolicy, Allocator> type;
Policy, Mixin, Allocator> type;
};
};
@ -320,15 +331,16 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename ThreadingPolicy = BOOST_FUNCTION_DEFAULT_THREADING_POLICY,
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = std::allocator<function_base>
>
struct get_function_impl
{
typedef typename real_get_function_impl<
(count_used_args<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value)
>::template params<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
ThreadingPolicy, Allocator>::type
Policy, Mixin, Allocator>::type
type;
};
@ -344,37 +356,55 @@ namespace boost {
typename T8,
typename T9,
typename T10,
typename MyThreadingPolicy = BOOST_FUNCTION_DEFAULT_THREADING_POLICY,
typename MyAllocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
typename MyPolicy = empty_function_policy,
typename MyMixin = empty_function_mixin,
typename MyAllocator = std::allocator<function_base>
>
struct function_traits_builder
{
typedef typename get_function_impl<R, T1, T2, T3, T4, T5, T6, T7,
T8, T9, T10, MyThreadingPolicy,
T8, T9, T10, MyPolicy, MyMixin,
MyAllocator>::type
type;
typedef MyThreadingPolicy threading_policy_type;
typedef MyPolicy policy_type;
typedef MyMixin mixin_type;
typedef MyAllocator allocator_type;
#ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
template<typename ThreadingPolicy>
struct threading_policy :
template<typename Policy>
struct policy :
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
T10, ThreadingPolicy,
T10, Policy, mixin_type,
allocator_type> {};
template<typename Mixin>
struct mixin :
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
T10, policy_type, Mixin,
allocator_type> {};
template<typename Allocator>
struct allocator :
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
T10, threading_policy_type,
T10, policy_type, mixin_type,
Allocator> {};
#else
template<typename ThreadingPolicy>
struct threading_policy
template<typename Policy>
struct policy
{
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
T8, T9, T10, ThreadingPolicy,
T8, T9, T10, Policy,
mixin_type,
allocator_type>::type
type;
};
template<typename Mixin>
struct mixin
{
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
T8, T9, T10, policy_type, Mixin,
allocator_type>::type
type;
};
@ -383,9 +413,8 @@ namespace boost {
struct allocator
{
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
T8, T9, T10,
threading_policy_type,
Allocator>::type
T8, T9, T10, policy_type,
mixin_type, Allocator>::type
type;
};
#endif
@ -419,7 +448,8 @@ namespace boost {
base_type;
public:
typedef typename base_type::threading_policy_type policy_type;
typedef typename base_type::policy_type policy_type;
typedef typename base_type::mixin_type mixin_type;
typedef typename base_type::allocator_type allocator_type;
typedef function self_type;
@ -433,21 +463,37 @@ namespace boost {
template<typename Functor>
self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{
base_type::operator=(f);
self_type(f).swap(*this);
return *this;
}
self_type& operator=(const base_type& f)
{
base_type::operator=(f);
self_type(f).swap(*this);
return *this;
}
self_type& operator=(const self_type& f)
{
base_type::operator=(static_cast<const base_type&>(f));
self_type(f).swap(*this);
return *this;
}
template<typename Functor>
void set(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{
self_type(f).swap(*this);
}
void set(const base_type& f)
{
self_type(f).swap(*this);
}
void set(const self_type& f)
{
self_type(f).swap(*this);
}
};
template<typename R,

View File

@ -1,6 +1,6 @@
// Boost.Function library
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
@ -24,8 +24,6 @@
#include <boost/config.hpp>
#include <boost/type_traits.hpp>
#include <boost/ref.hpp>
#include <boost/function/threading/single.hpp>
#include <boost/pending/ct_if.hpp>
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406
# define BOOST_FUNCTION_TARGET_FIX(x) x
@ -33,21 +31,51 @@
# define BOOST_FUNCTION_TARGET_FIX(x)
#endif // not MSVC
#ifndef BOOST_FUNCTION_DEFAULT_THREADING_POLICY
# define BOOST_FUNCTION_DEFAULT_THREADING_POLICY single_threaded
#endif
// Type of the default allocator
#ifndef BOOST_NO_STD_ALLOCATOR
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
#else
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
#endif // BOOST_NO_STD_ALLOCATOR
namespace boost {
namespace detail {
namespace function {
template<bool> struct truth {};
/*
* The IF implementation is temporary code. When a Boost metaprogramming
* library is introduced, Boost.Function will use it instead.
*/
namespace intimate {
struct SelectThen
{
template<typename Then, typename Else>
struct Result
{
typedef Then type;
};
};
struct SelectElse
{
template<typename Then, typename Else>
struct Result
{
typedef Else type;
};
};
template<bool Condition>
struct Selector
{
typedef SelectThen type;
};
template<>
struct Selector<false>
{
typedef SelectElse type;
};
} // end namespace intimate
template<bool Condition, typename Then, typename Else>
struct IF
{
typedef typename intimate::Selector<Condition>::type select;
typedef typename select::template Result<Then,Else>::type type;
};
/**
* A union of a function pointer and a void pointer. This is necessary
@ -107,20 +135,20 @@ namespace boost {
template<typename F>
class get_function_tag
{
typedef typename ct_if<(is_pointer<F>::value),
typedef typename IF<(is_pointer<F>::value),
function_ptr_tag,
function_obj_tag>::type ptr_or_obj_tag;
typedef typename ct_if<(is_member_pointer<F>::value),
typedef typename IF<(is_member_pointer<F>::value),
member_ptr_tag,
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
typedef typename ct_if<(is_reference_wrapper<F>::value),
typedef typename IF<(is_reference_wrapper<F>::value),
function_obj_ref_tag,
ptr_or_obj_or_mem_tag>::type or_ref_tag;
public:
typedef typename ct_if<(is_stateless<F>::value),
typedef typename IF<(is_stateless<F>::value),
stateless_function_obj_tag,
or_ref_tag>::type type;
};
@ -128,7 +156,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;
@ -148,8 +176,7 @@ 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)
@ -280,10 +307,6 @@ 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() {};
@ -294,7 +317,6 @@ namespace boost {
public:
operator safe_bool () const
{ return (this->empty())? 0 : &dummy::nonnull; }
#endif
safe_bool operator!() const
{ return (this->empty())? &dummy::nonnull : 0; }
@ -311,35 +333,112 @@ namespace boost {
namespace detail {
namespace function {
// The result is not a Boost.Function object, so we assume that this
// target is not empty
template<typename FunctionObj>
inline bool has_empty_target(const FunctionObj&, truth<false>)
{
return false;
}
/**
* Determine if the given target is empty.
*/
// The result is a Boost.Function object, so query whether it is empty
// or not
template<typename FunctionObj>
inline bool has_empty_target(const FunctionObj& f, truth<true>)
// Fallback - assume target is not empty
inline bool has_empty_target(...)
{
return f.empty();
return false;
}
// If the target is a 'function', query the empty() method
inline bool has_empty_target(const function_base* af)
{
return af->empty();
}
template<typename Lock, typename Mixin>
struct scoped_double_lock
// 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)())
{
scoped_double_lock(const Mixin& m1, const Mixin& m2) :
lock1(&m1 < &m2? m1 : m2), lock2(!(&m1 < &m2)? m1 : m2)
{
}
Lock lock1;
Lock lock2;
};
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;
}
} // end namespace function
} // end namespace detail
// The default function policy is to do nothing before and after the call.
struct empty_function_policy
{
inline void precall(const function_base*) {}
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&) {};
empty_function_mixin& operator=(const empty_function_mixin&)
{return *this; }
};
}
#endif // BOOST_FUNCTION_BASE_HEADER

View File

@ -1,6 +1,6 @@
// Boost.Function library
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
@ -25,6 +25,13 @@
# include <boost/mem_fn.hpp>
#endif // BOOST_FUNCTION_FUNCTION_TEMPLATE_HPP
// Type of the default allocator
#ifndef BOOST_NO_STD_ALLOCATOR
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
#else
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
#endif // BOOST_NO_STD_ALLOCATOR
// Comma if nonzero number of arguments
#if BOOST_FUNCTION_NUM_ARGS == 0
# define BOOST_FUNCTION_COMMA
@ -34,6 +41,7 @@
// 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 \
@ -160,7 +168,7 @@ namespace boost {
>
struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
{
typedef typename ct_if<(is_void<R>::value),
typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
FunctionPtr,
R BOOST_FUNCTION_COMMA
@ -181,7 +189,7 @@ namespace boost {
>
struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
{
typedef typename ct_if<(is_void<R>::value),
typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
FunctionObj,
R BOOST_FUNCTION_COMMA
@ -202,7 +210,7 @@ namespace boost {
>
struct BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
{
typedef typename ct_if<(is_void<R>::value),
typedef typename IF<(is_void<R>::value),
BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER<
FunctionObj,
R BOOST_FUNCTION_COMMA
@ -222,18 +230,15 @@ namespace boost {
template<
typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS,
typename ThreadingPolicy = BOOST_FUNCTION_DEFAULT_THREADING_POLICY,
typename Policy = empty_function_policy,
typename Mixin = empty_function_mixin,
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
>
class BOOST_FUNCTION_FUNCTION : public function_base,
public ThreadingPolicy::mixin
class BOOST_FUNCTION_FUNCTION : public function_base, public Mixin
{
typedef typename detail::function::function_return_type<R>::type
internal_result_type;
typedef typename ThreadingPolicy::mixin threading_mixin;
typedef typename ThreadingPolicy::lock lock;
public:
BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
@ -249,48 +254,54 @@ namespace boost {
#else
typedef internal_result_type result_type;
#endif // BOOST_NO_VOID_RETURNS
typedef Policy policy_type;
typedef Mixin mixin_type;
typedef Allocator allocator_type;
typedef BOOST_FUNCTION_FUNCTION self_type;
typedef ThreadingPolicy threading_policy_type;
BOOST_FUNCTION_FUNCTION() : function_base(), invoker(0) {}
BOOST_FUNCTION_FUNCTION() : function_base(), Mixin(), invoker(0) {}
explicit BOOST_FUNCTION_FUNCTION(const Mixin& m) :
function_base(), Mixin(m), invoker(0)
{
}
// MSVC chokes if the following two constructors are collapsed into
// one with a default parameter.
template<typename Functor>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) :
function_base(), invoker(0)
function_base(), Mixin(), invoker(0)
{
this->assign_to(f);
}
template<typename Functor>
BOOST_FUNCTION_FUNCTION(Functor f, const Mixin& m) :
function_base(), Mixin(m), invoker(0)
{
this->assign_to(f);
}
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) :
function_base(), invoker(0)
function_base(), Mixin(static_cast<const Mixin&>(f)), invoker(0)
{
// Lock the other function object so it can't change during assignment
lock l(static_cast<const self_type&>(f));
(void)l;
this->assign_to_own(f);
}
~BOOST_FUNCTION_FUNCTION()
{
lock l(static_cast<const threading_mixin&>(*this));
(void)l;
clear();
}
~BOOST_FUNCTION_FUNCTION() { clear(); }
result_type operator()(BOOST_FUNCTION_PARMS) const
{
// Make sure this function can't change while it is being invoked
lock l(static_cast<const threading_mixin&>(*this));
(void)l;
assert(!this->empty());
policy_type policy;
policy.precall(this);
internal_result_type result = invoker(function_base::functor
BOOST_FUNCTION_COMMA
BOOST_FUNCTION_ARGS);
policy.postcall(this);
#ifndef BOOST_NO_VOID_RETURNS
return static_cast<result_type>(result);
#else
@ -307,51 +318,52 @@ namespace boost {
BOOST_FUNCTION_FUNCTION&
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{
self_type other(f);
lock l(static_cast<const threading_mixin&>(*this));
(void)l;
other.unlocked_swap(*this);
self_type(f, static_cast<const Mixin&>(*this)).swap(*this);
return *this;
}
template<typename Functor>
void set(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
{
self_type(f, static_cast<const Mixin&>(*this)).swap(*this);
}
// Assignment from another BOOST_FUNCTION_FUNCTION
BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
{
if (&f == this)
return *this;
self_type other(f);
lock l(static_cast<const threading_mixin&>(*this));
(void)l;
other.unlocked_swap(*this);
self_type(f).swap(*this);
return *this;
}
// Assignment from another BOOST_FUNCTION_FUNCTION
void set(const BOOST_FUNCTION_FUNCTION& f)
{
if (&f == this)
return;
self_type(f).swap(*this);
}
void swap(BOOST_FUNCTION_FUNCTION& other)
{
if (&other == this)
return;
detail::function::scoped_double_lock<lock, threading_mixin> l(*this,
other);
(void)l;
unlocked_swap(other);
std::swap(function_base::manager, other.manager);
std::swap(function_base::functor, other.functor);
std::swap(invoker, other.invoker);
std::swap(static_cast<Mixin&>(*this), static_cast<Mixin&>(other));
}
// Clear out a target, if there is one
void clear()
{
lock l(static_cast<const threading_mixin&>(*this));
(void)l;
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;
}
@ -362,9 +374,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);
}
}
template<typename Functor>
@ -388,10 +399,9 @@ 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)
@ -411,11 +421,7 @@ namespace boost {
template<typename FunctionObj>
void assign_to(FunctionObj f, detail::function::function_obj_tag)
{
typedef detail::function::truth<
boost::is_base_and_derived<function_base, FunctionObj>::value>
is_boost_function;
if (!detail::function::has_empty_target(f, is_boost_function())) {
if (!detail::function::has_empty_target(&f)) {
typedef
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
FunctionObj,
@ -425,23 +431,11 @@ namespace boost {
invoker_type;
invoker = &invoker_type::invoke;
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::manager = &detail::function::functor_manager<FunctionObj,
Allocator>::manage;
function_base::functor =
detail::function::any_pointer(static_cast<void*>(new_f));
function_base::manager(detail::function::any_pointer(const_cast<FunctionObj*>(&f)),
detail::function::clone_functor_tag);
}
}
@ -449,11 +443,7 @@ namespace boost {
void assign_to(const reference_wrapper<FunctionObj>& f,
detail::function::function_obj_ref_tag)
{
typedef detail::function::truth<
boost::is_base_and_derived<function_base, FunctionObj>::value>
is_boost_function;
if (!detail::function::has_empty_target(f.get(), is_boost_function())) {
if (!detail::function::has_empty_target(&f.get())) {
typedef
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
FunctionObj,
@ -465,10 +455,9 @@ 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_pointer())),
detail::function::clone_functor_tag);
function_base::manager(detail::function::any_pointer(
const_cast<FunctionObj*>(&f.get())),
detail::function::clone_functor_tag);
}
}
@ -488,13 +477,6 @@ namespace boost {
function_base::functor = detail::function::any_pointer(this);
}
void unlocked_swap(BOOST_FUNCTION_FUNCTION& other)
{
std::swap(function_base::manager, other.manager);
std::swap(function_base::functor, other.functor);
std::swap(invoker, other.invoker);
}
typedef internal_result_type (*invoker_type)(detail::function::any_pointer
BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS);
@ -503,17 +485,19 @@ namespace boost {
};
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename ThreadingPolicy, typename Allocator>
typename Policy, typename Mixin, typename Allocator>
inline void swap(BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS ,
ThreadingPolicy,
Policy,
Mixin,
Allocator
>& f1,
BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS,
ThreadingPolicy,
Policy,
Mixin,
Allocator
>& f2)
{
@ -522,8 +506,11 @@ namespace boost {
}
// Cleanup after ourselves...
#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
@ -534,3 +521,4 @@ namespace boost {
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
#undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER

View File

@ -1,48 +0,0 @@
// Copyright (C) 2002
// Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_MODEL_DETAIL_MUTEX_MIXIN_HPP
#define BOOST_THREAD_MODEL_DETAIL_MUTEX_MIXIN_HPP
namespace boost {
namespace detail {
template<typename Mutex>
class mutex_mixin
{
public:
mutex_mixin(const mutex_mixin&) {}
mutex_mixin& operator=(const mutex_mixin&) { return *this; }
operator const Mutex&() const { return mutex; }
operator Mutex&() { return mutex; }
private:
Mutex mutex;
};
template<typename Mutex>
class static_mutex_mixin
{
public:
static_mutex_mixin(const mutex_mixin&) {}
static_mutex_mixin& operator=(const mutex_mixin&) { return *this; }
operator const Mutex&() const { return mutex; }
operator Mutex&() { return mutex; }
private:
static Mutex mutex;
};
} // end namespace detail
} // end namespace boost
#endif // BOOST_THREAD_MODEL_DETAIL_MUTEX_MIXIN_HPP

View File

@ -1,28 +0,0 @@
// Copyright (C) 2002
// Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_MODEL_PER_CLASS_HPP
#define BOOST_THREAD_MODEL_PER_CLASS_HPP
#include <boost/thread/mutex.hpp>
#include <boost/thread/model/detail/mutex_mixin.hpp>
namespace boost {
template<typename Mutex = boost::mutex>
struct per_class_locking
{
typedef detail::static_mutex_mixin<Mutex> mixin;
typedef typename Mutex::scoped_lock lock;
};
} // end namespace boost
#endif // BOOST_THREAD_MODEL_PER_CLASS_HPP

View File

@ -1,28 +0,0 @@
// Copyright (C) 2002
// Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_MODEL_PER_OBJECT_HPP
#define BOOST_THREAD_MODEL_PER_OBJECT_HPP
#include <boost/thread/mutex.hpp>
#include <boost/thread/model/detail/mutex_mixin.hpp>
namespace boost {
template<typename Mutex = boost::mutex>
struct per_object_locking
{
typedef detail::mutex_mixin<Mutex> mixin;
typedef typename Mutex::scoped_lock lock;
};
} // end namespace boost
#endif // BOOST_THREAD_MODEL_PER_OBJECT_HPP

View File

@ -1,27 +0,0 @@
// Copyright (C) 2002
// Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. William E. Kempf makes no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
#ifndef BOOST_THREAD_MODEL_SINGLE_HPP
#define BOOST_THREAD_MODEL_SINGLE_HPP
namespace boost {
struct single_threaded {
struct mixin {};
struct lock
{
lock(const mixin&) {}
};
};
} // end namespace boost
#endif // BOOST_THREAD_MODEL_SINGLE_HPP

View File

@ -1,6 +1,6 @@
// Boost.Function library
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
@ -93,7 +93,7 @@ test_zero_args()
// Invocation and self-assignment
global_int = 0;
v1 = (v1);
v1.set(v1);
v1();
BOOST_TEST(global_int == 5);
@ -152,7 +152,7 @@ test_zero_args()
BOOST_TEST(global_int == 3);
// Assignment to a non-empty function
v2 = (five);
v2.set(five);
// Invocation
global_int = 0;
@ -163,7 +163,7 @@ test_zero_args()
BOOST_TEST(v2.empty());
// Assignment to an empty function from a free function
v2 = (&write_five);
v2.set(&write_five);
BOOST_TEST(v2);
// Invocation

View File

@ -1,6 +1,6 @@
// Boost.Function library
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
@ -93,7 +93,7 @@ test_zero_args()
// Invocation and self-assignment
global_int = 0;
v1 = (v1);
v1.set(v1);
v1();
BOOST_TEST(global_int == 5);
@ -152,7 +152,7 @@ test_zero_args()
BOOST_TEST(global_int == 3);
// Assignment to a non-empty function
v2 = (five);
v2.set(five);
// Invocation
global_int = 0;
@ -163,7 +163,7 @@ test_zero_args()
BOOST_TEST(v2.empty());
// Assignment to an empty function from a free function
v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
v2.set(BOOST_FUNCTION_TARGET_FIX(&) write_five);
BOOST_TEST(v2);
// Invocation

60
test/mixin_test.cpp Normal file
View File

@ -0,0 +1,60 @@
// Boost.Function library
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// For more information, see http://www.boost.org
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <cassert>
#include <functional>
#include <boost/function.hpp>
struct id_mixin
{
id_mixin(const id_mixin& rhs) : id(rhs.id) {}
id_mixin& operator=(const id_mixin& rhs){id = rhs.id; return *this;}
id_mixin(int i = 0){ id = i;}
int id;
};
static int do_plus(int x, int y) { return x+y; }
typedef boost::function<int,int,int>::mixin<id_mixin>::type func;
int test_main(int, char*[])
{
func f(id_mixin(3));
f = std::plus<int>();
BOOST_TEST(f.id == 3);
f = &do_plus;
BOOST_TEST(f.id == 3);
f.clear();
f.id = 7;
BOOST_TEST(f.id == 7);
func g(f);
BOOST_TEST(g.id == 7);
f.id = 21;
BOOST_TEST(f.id == 21);
boost::swap(f,g);
BOOST_TEST(f.id == 7);
BOOST_TEST(g.id == 21);
g = f;
BOOST_TEST(g.id == 7);
return 0;
}

47
test/policy_test.cpp Normal file
View File

@ -0,0 +1,47 @@
// Boost.Function library
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// For more information, see http://www.boost.org
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <cassert>
#include <iostream>
#include <functional>
#include <boost/function.hpp>
using namespace std;
using namespace boost;
struct counting_policy
{
static int count;
void precall(const function_base*) { count++; }
void postcall(const function_base*) { count+=2; }
};
int counting_policy::count = 0;
int
test_main(int, char*[])
{
function<int, int, int>::policy<counting_policy>::type f;
f = plus<int>();
BOOST_TEST(5 == f(2,3));
BOOST_TEST(counting_policy::count==3);
return 0;
}