Compare commits

..

9 Commits

Author SHA1 Message Date
0dcec9ffb9 function_base.hpp:
- Fixed strange patch weirdness on Sun WorkShop C++


[SVN r13855]
2002-05-14 14:34:21 +00:00
4d635501ab function_base.hpp:
function_template.hpp:
  - Revert to older implementation of has_empty_function (Metrowerks doesn't
    handle is_base_and_derived correctly)


[SVN r13854]
2002-05-14 14:18:36 +00:00
d1f21800ac Lambda is now a Boost library
[SVN r13831]
2002-05-13 12:33:19 +00:00
092cb0d706 This commit was manufactured by cvs2svn to create branch 'RC_1_28_0'.
[SVN r13795]
2002-05-10 04:34:27 +00:00
57ee7e962a function.hpp:
- Remove default parameters in real_get_function_impl (Fixed Borland C++
    Builder 6)


[SVN r13595]
2002-04-30 20:05:32 +00:00
48943fec83 Removed some unused macros
[SVN r13594]
2002-04-30 19:41:37 +00:00
a0b89d0a30 function_base.hpp:
- Workaround for Sun CC


[SVN r13566]
2002-04-26 17:45:53 +00:00
82226cb9d6 Changed IF to ct_if because IF is sometimes used as a macro (ewww)
[SVN r13420]
2002-04-10 04:10:06 +00:00
28984e4f23 function_base.hpp:
- has_empty_target modified to deal only with function objects, and to not
    require pointers to the function objects.

function_template.hpp:
  - Don't use '&' operation on incoming function objects


[SVN r13318]
2002-03-30 18:45:28 +00:00
4 changed files with 103 additions and 155 deletions

View File

@ -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&lt;float, int, int, SynchronizedPolicy, SynchronizedMixin&gt; 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>

View File

@ -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
{

View File

@ -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;
}
};
}

View File

@ -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