forked from boostorg/bind
__fastcall support added.
[SVN r14465]
This commit is contained in:
60
bind.html
60
bind.html
@@ -46,7 +46,7 @@
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_mac">Does <b>bind</b> work with Mac toolbox
|
||||
functions?</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_extern_C">Does <b>bind</b> work with extern
|
||||
"C" functions?</a></h4>
|
||||
"C" functions?</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_auto_stdcall">Why doesn't <b>bind</b> automatically
|
||||
recognize nonstandard functions?</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Troubleshooting">Troubleshooting</a></h3>
|
||||
@@ -77,7 +77,8 @@
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Files">Files</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Dependencies">Dependencies</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#NumberOfArguments">Number of Arguments</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall" and "pascal" Support</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall", "__fastcall", and
|
||||
"pascal" Support</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#BOOST_BIND">Using the BOOST_BIND macro</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#visit_each"><b>visit_each</b> support</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Acknowledgements">Acknowledgements</a></h3>
|
||||
@@ -455,13 +456,13 @@ template<class T> void f(T const & t);
|
||||
alternative is to treat the function as a <a href="#with_function_objects">generic
|
||||
function object</a> and use the bind<R>(f, ...) syntax.
|
||||
</p>
|
||||
<h3><a name="Q_extern_C">Does <b>bind</b> work with extern "C" functions?</a></h3>
|
||||
<h3><a name="Q_extern_C">Does <b>bind</b> work with extern "C" functions?</a></h3>
|
||||
<p>
|
||||
Sometimes. On some platforms, pointers to extern "C" functions are
|
||||
equivalent to "ordinary" function pointers, so they work fine. Other
|
||||
platforms treat them as different types. A platform-specific implementation of <b>bind</b>
|
||||
is expected to handle the problem transparently; this implementation does not.
|
||||
As usual, the workaround is to treat the function as a <a href="#with_function_objects">
|
||||
Sometimes. On some platforms, pointers to extern "C" functions are equivalent
|
||||
to "ordinary" function pointers, so they work fine. Other platforms treat them
|
||||
as different types. A platform-specific implementation of <b>bind</b> is
|
||||
expected to handle the problem transparently; this implementation does not. As
|
||||
usual, the workaround is to treat the function as a <a href="#with_function_objects">
|
||||
generic function object</a> and use the bind<R>(f, ...) syntax.
|
||||
</p>
|
||||
<h3><a name="Q_auto_stdcall">Why doesn't <b>bind</b> automatically recognize
|
||||
@@ -471,8 +472,9 @@ template<class T> void f(T const & t);
|
||||
lock-in. Had the <a href="#stdcall">appropriate macros</a> been defined
|
||||
automatically, you could have accidentally taken advantage of them without
|
||||
realizing that your code is, perhaps, no longer portable. In addition, some
|
||||
compilers have the option to make <b>__stdcall</b> their default calling
|
||||
convention, in which case no separate support would be necessary.
|
||||
compilers have the option to make <b>__stdcall</b> (<STRONG>__fastcall</STRONG>)
|
||||
their default calling convention, in which case no separate support would be
|
||||
necessary.
|
||||
</p>
|
||||
<h2><a name="Troubleshooting">Troubleshooting</a></h2>
|
||||
<h3><a name="err_num_args">Incorrect number of arguments</a></h3>
|
||||
@@ -589,7 +591,7 @@ int main()
|
||||
a2, ..., aN) <A href="#Q_forms">form</A> works with nonstandard functions.
|
||||
</p>
|
||||
<p>
|
||||
On some platforms, extern "C" functions, like <b>std::strcmp</b>, are not
|
||||
On some platforms, extern "C" functions, like <b>std::strcmp</b>, are not
|
||||
recognized by the short form of bind.
|
||||
</p>
|
||||
<P>
|
||||
@@ -753,8 +755,8 @@ namespace
|
||||
<b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F>(f);</tt>
|
||||
</p>
|
||||
<p>
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b>
|
||||
via other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
|
||||
other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_2">template<class R> <i>unspecified-2</i> bind(R (*f) ())</a></h4>
|
||||
@@ -789,8 +791,8 @@ namespace
|
||||
a1);</tt>
|
||||
</p>
|
||||
<p>
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b>
|
||||
via other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
|
||||
other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_4">template<class R, class B1, class A1> <i>unspecified-4</i> bind(R
|
||||
@@ -822,8 +824,8 @@ namespace
|
||||
a1);</tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_6_1">template<class R, class T, class A1> <i>unspecified-6-1</i> bind(R
|
||||
T::*f, A1 a1)</a></h4>
|
||||
<h4><a name="bind_6_1">template<class R, class T, class A1> <i>unspecified-6-1</i>
|
||||
bind(R T::*f, A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> Equivalent to <tt>bind<R const &>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
@@ -852,8 +854,8 @@ namespace
|
||||
a1, a2);</tt>
|
||||
</p>
|
||||
<p>
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b>
|
||||
via other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
|
||||
other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_8">template<class R, class B1, class B2, class A1, class A2> <i>unspecified-8</i>
|
||||
@@ -888,8 +890,8 @@ namespace
|
||||
</blockquote>
|
||||
<h3><a name="AdditionalOverloads">Additional overloads</a></h3>
|
||||
<p>
|
||||
Implementations are allowed to provide additional <b>bind</b> overloads in order to
|
||||
support more arguments or different function pointer variations.
|
||||
Implementations are allowed to provide additional <b>bind</b> overloads in
|
||||
order to support more arguments or different function pointer variations.
|
||||
</p>
|
||||
<h2><a name="Implementation">Implementation</a></h2>
|
||||
<h3><a name="Files">Files</a></h3>
|
||||
@@ -951,7 +953,7 @@ namespace
|
||||
This implementation supports function objects with up to nine arguments. This
|
||||
is an implementation detail, not an inherent limitation of the design.
|
||||
</p>
|
||||
<h3><a name="stdcall">"__stdcall" and "pascal" Support</a></h3>
|
||||
<h3><a name="stdcall">"__stdcall", "__fastcall", and "pascal" Support</a></h3>
|
||||
<p>
|
||||
Some platforms allow several types of (member) functions that differ by their <b>calling
|
||||
convention</b> (the rules by which the function is invoked: how are
|
||||
@@ -960,8 +962,8 @@ namespace
|
||||
</p>
|
||||
<p>
|
||||
For example, Windows API functions and COM interface member functions use a
|
||||
calling convention known as <b>__stdcall</b>. Mac toolbox functions use a <b>pascal</b>
|
||||
calling convention.
|
||||
calling convention known as <b>__stdcall</b>.Borland VCL components use <STRONG>__fastcall</STRONG>.
|
||||
Mac toolbox functions use a <b>pascal</b> calling convention.
|
||||
</p>
|
||||
<p>
|
||||
To use <b>bind</b> with <b>__stdcall</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_STDCALL</b>
|
||||
@@ -971,10 +973,16 @@ namespace
|
||||
To use <b>bind</b> with <b>__stdcall</b> <b>member</b> functions, <b>#define</b>
|
||||
the macro <b>BOOST_MEM_FN_ENABLE_STDCALL</b> before including <b><boost/bind.hpp></b>.
|
||||
</p>
|
||||
<p>
|
||||
<P>To use <B>bind</B> with <B>__fastcall</B> functions, <B>#define</B> the macro <B>BOOST_BIND_ENABLE_FASTCALL</B>
|
||||
before including <B><boost/bind.hpp></B>.
|
||||
</P>
|
||||
<P>To use <B>bind</B> with <B>__fastcall</B> <B>member</B> functions, <B>#define</B>
|
||||
the macro <B>BOOST_MEM_FN_ENABLE_FASTCALL</B> before including <B><boost/bind.hpp></B>.
|
||||
</P>
|
||||
<P>
|
||||
To use <b>bind</b> with <b>pascal</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_PASCAL</b>
|
||||
before including <b><boost/bind.hpp></b>.
|
||||
</p>
|
||||
</P>
|
||||
<p>
|
||||
[Note: this is a non-portable extension. It is not part of the interface.]
|
||||
</p>
|
||||
|
165
bind_fastcall_mf_test.cpp
Normal file
165
bind_fastcall_mf_test.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// bind_stdcall_mf_test.cpp - test for bind.hpp + __stdcall (member functions)
|
||||
//
|
||||
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#define BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
mutable unsigned int hash;
|
||||
|
||||
X(): hash(0) {}
|
||||
|
||||
void __fastcall f0() { f1(17); }
|
||||
void __fastcall g0() const { g1(17); }
|
||||
|
||||
void __fastcall f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
|
||||
void __fastcall g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
|
||||
|
||||
void __fastcall f2(int a1, int a2) { f1(a1); f1(a2); }
|
||||
void __fastcall g2(int a1, int a2) const { g1(a1); g1(a2); }
|
||||
|
||||
void __fastcall f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
|
||||
void __fastcall g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
|
||||
|
||||
void __fastcall f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
|
||||
void __fastcall g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
|
||||
|
||||
void __fastcall f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
|
||||
void __fastcall g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
|
||||
|
||||
void __fastcall f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
|
||||
void __fastcall g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
|
||||
|
||||
void __fastcall f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
|
||||
void __fastcall g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
|
||||
|
||||
void __fastcall f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
|
||||
void __fastcall g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
|
||||
};
|
||||
|
||||
void member_function_test()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
X x;
|
||||
|
||||
// 0
|
||||
|
||||
bind(&X::f0, &x)();
|
||||
bind(&X::f0, ref(x))();
|
||||
|
||||
bind(&X::g0, &x)();
|
||||
bind(&X::g0, x)();
|
||||
bind(&X::g0, ref(x))();
|
||||
|
||||
// 1
|
||||
|
||||
bind(&X::f1, &x, 1)();
|
||||
bind(&X::f1, ref(x), 1)();
|
||||
|
||||
bind(&X::g1, &x, 1)();
|
||||
bind(&X::g1, x, 1)();
|
||||
bind(&X::g1, ref(x), 1)();
|
||||
|
||||
// 2
|
||||
|
||||
bind(&X::f2, &x, 1, 2)();
|
||||
bind(&X::f2, ref(x), 1, 2)();
|
||||
|
||||
bind(&X::g2, &x, 1, 2)();
|
||||
bind(&X::g2, x, 1, 2)();
|
||||
bind(&X::g2, ref(x), 1, 2)();
|
||||
|
||||
// 3
|
||||
|
||||
bind(&X::f3, &x, 1, 2, 3)();
|
||||
bind(&X::f3, ref(x), 1, 2, 3)();
|
||||
|
||||
bind(&X::g3, &x, 1, 2, 3)();
|
||||
bind(&X::g3, x, 1, 2, 3)();
|
||||
bind(&X::g3, ref(x), 1, 2, 3)();
|
||||
|
||||
// 4
|
||||
|
||||
bind(&X::f4, &x, 1, 2, 3, 4)();
|
||||
bind(&X::f4, ref(x), 1, 2, 3, 4)();
|
||||
|
||||
bind(&X::g4, &x, 1, 2, 3, 4)();
|
||||
bind(&X::g4, x, 1, 2, 3, 4)();
|
||||
bind(&X::g4, ref(x), 1, 2, 3, 4)();
|
||||
|
||||
// 5
|
||||
|
||||
bind(&X::f5, &x, 1, 2, 3, 4, 5)();
|
||||
bind(&X::f5, ref(x), 1, 2, 3, 4, 5)();
|
||||
|
||||
bind(&X::g5, &x, 1, 2, 3, 4, 5)();
|
||||
bind(&X::g5, x, 1, 2, 3, 4, 5)();
|
||||
bind(&X::g5, ref(x), 1, 2, 3, 4, 5)();
|
||||
|
||||
// 6
|
||||
|
||||
bind(&X::f6, &x, 1, 2, 3, 4, 5, 6)();
|
||||
bind(&X::f6, ref(x), 1, 2, 3, 4, 5, 6)();
|
||||
|
||||
bind(&X::g6, &x, 1, 2, 3, 4, 5, 6)();
|
||||
bind(&X::g6, x, 1, 2, 3, 4, 5, 6)();
|
||||
bind(&X::g6, ref(x), 1, 2, 3, 4, 5, 6)();
|
||||
|
||||
// 7
|
||||
|
||||
bind(&X::f7, &x, 1, 2, 3, 4, 5, 6, 7)();
|
||||
bind(&X::f7, ref(x), 1, 2, 3, 4, 5, 6, 7)();
|
||||
|
||||
bind(&X::g7, &x, 1, 2, 3, 4, 5, 6, 7)();
|
||||
bind(&X::g7, x, 1, 2, 3, 4, 5, 6, 7)();
|
||||
bind(&X::g7, ref(x), 1, 2, 3, 4, 5, 6, 7)();
|
||||
|
||||
// 8
|
||||
|
||||
bind(&X::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
bind(&X::f8, ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
|
||||
bind(&X::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
bind(&X::g8, x, 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
bind(&X::g8, ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
|
||||
BOOST_TEST( x.hash == 23558 );
|
||||
}
|
||||
|
||||
int test_main(int, char * [])
|
||||
{
|
||||
member_function_test();
|
||||
return 0;
|
||||
}
|
110
bind_fastcall_test.cpp
Normal file
110
bind_fastcall_test.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// bind_fastcall_test.cpp - test for bind.hpp + __fastcall (free functions)
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#define BOOST_BIND_ENABLE_FASTCALL
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
//
|
||||
|
||||
long __fastcall f_0()
|
||||
{
|
||||
return 17041L;
|
||||
}
|
||||
|
||||
long __fastcall f_1(long a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
long __fastcall f_2(long a, long b)
|
||||
{
|
||||
return a + 10 * b;
|
||||
}
|
||||
|
||||
long __fastcall f_3(long a, long b, long c)
|
||||
{
|
||||
return a + 10 * b + 100 * c;
|
||||
}
|
||||
|
||||
long __fastcall f_4(long a, long b, long c, long d)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d;
|
||||
}
|
||||
|
||||
long __fastcall f_5(long a, long b, long c, long d, long e)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e;
|
||||
}
|
||||
|
||||
long __fastcall f_6(long a, long b, long c, long d, long e, long f)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
|
||||
}
|
||||
|
||||
long __fastcall f_7(long a, long b, long c, long d, long e, long f, long g)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
|
||||
}
|
||||
|
||||
long __fastcall f_8(long a, long b, long c, long d, long e, long f, long g, long h)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
|
||||
}
|
||||
|
||||
long __fastcall f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
|
||||
}
|
||||
|
||||
void function_test()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
int const i = 1;
|
||||
|
||||
BOOST_TEST( bind(f_0)(i) == 17041L );
|
||||
BOOST_TEST( bind(f_1, _1)(i) == 1L );
|
||||
BOOST_TEST( bind(f_2, _1, 2)(i) == 21L );
|
||||
BOOST_TEST( bind(f_3, _1, 2, 3)(i) == 321L );
|
||||
BOOST_TEST( bind(f_4, _1, 2, 3, 4)(i) == 4321L );
|
||||
BOOST_TEST( bind(f_5, _1, 2, 3, 4, 5)(i) == 54321L );
|
||||
BOOST_TEST( bind(f_6, _1, 2, 3, 4, 5, 6)(i) == 654321L );
|
||||
BOOST_TEST( bind(f_7, _1, 2, 3, 4, 5, 6, 7)(i) == 7654321L );
|
||||
BOOST_TEST( bind(f_8, _1, 2, 3, 4, 5, 6, 7, 8)(i) == 87654321L );
|
||||
BOOST_TEST( bind(f_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i) == 987654321L );
|
||||
}
|
||||
|
||||
int test_main(int, char * [])
|
||||
{
|
||||
function_test();
|
||||
return 0;
|
||||
}
|
@@ -1343,6 +1343,18 @@ template<class F, class A1, class A2, class A3, class A4, class A5, class A6, cl
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_BIND_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_BIND_CC __fastcall
|
||||
#define BOOST_BIND_ST
|
||||
|
||||
#include <boost/bind/bind_cc.hpp>
|
||||
|
||||
#undef BOOST_BIND_CC
|
||||
#undef BOOST_BIND_ST
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_BIND_ENABLE_PASCAL
|
||||
|
||||
#define BOOST_BIND_ST pascal
|
||||
@@ -1377,6 +1389,18 @@ template<class F, class A1, class A2, class A3, class A4, class A5, class A6, cl
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_BIND_MF_NAME(X) X##_fastcall
|
||||
#define BOOST_BIND_MF_CC __fastcall
|
||||
|
||||
#include <boost/bind/bind_mf_cc.hpp>
|
||||
|
||||
#undef BOOST_BIND_MF_NAME
|
||||
#undef BOOST_BIND_MF_CC
|
||||
|
||||
#endif
|
||||
|
||||
// data member pointers
|
||||
|
||||
template<class R, class T, class A1>
|
||||
|
@@ -66,6 +66,18 @@ template<class V> struct mf
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_template.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_CC
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_MEM_FN_RETURN
|
||||
|
||||
}; // struct mf<V>
|
||||
@@ -95,6 +107,18 @@ template<> struct mf<void>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_template.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_CC
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_MEM_FN_RETURN
|
||||
|
||||
}; // struct mf<void>
|
||||
@@ -126,6 +150,20 @@ template<> struct mf<void>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) X##_fastcall
|
||||
#define BOOST_MEM_FN_NAME2(X) inner_##X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_vw.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
#undef BOOST_MEM_FN_NAME2
|
||||
#undef BOOST_MEM_FN_CC
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace _mfi
|
||||
|
||||
#else // #ifdef BOOST_NO_VOID_RETURNS
|
||||
@@ -158,6 +196,18 @@ namespace _mfi
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_template.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_CC
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_MEM_FN_RETURN
|
||||
|
||||
} // namespace _mfi
|
||||
@@ -187,6 +237,18 @@ namespace _mfi
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_cc.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
#undef BOOST_MEM_FN_CC
|
||||
|
||||
#endif
|
||||
|
||||
// data member support
|
||||
|
||||
namespace _mfi
|
||||
|
16
mem_fn.html
16
mem_fn.html
@@ -37,7 +37,8 @@
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Files">Files</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Dependencies">Dependencies</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#NumberOfArguments">Number of Arguments</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall" Support</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall" and
|
||||
"__fastcall" Support</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Acknowledgements">Acknowledgements</a></h3>
|
||||
<h2><a name="Purpose">Purpose</a></h2>
|
||||
<p>
|
||||
@@ -321,7 +322,7 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
This implementation supports member functions with up to eight arguments. This
|
||||
is not an inherent limitation of the design, but an implementation detail.
|
||||
</p>
|
||||
<h3><a name="stdcall">"__stdcall" Support</a></h3>
|
||||
<h3><a name="stdcall">"__stdcall" and "__fastcall" Support</a></h3>
|
||||
<p>
|
||||
Some platforms allow several types of member functions that differ by their <b>calling
|
||||
convention</b> (the rules by which the function is invoked: how are
|
||||
@@ -330,16 +331,19 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
</p>
|
||||
<p>
|
||||
For example, Windows API functions and COM interface member functions use a
|
||||
calling convention known as <b>__stdcall</b>.
|
||||
calling convention known as <b>__stdcall</b>. Borland VCL components use <STRONG>__fastcall</STRONG>.
|
||||
</p>
|
||||
<p>
|
||||
To use <b>mem_fn</b> with <b>__stdcall</b> member functions, <b>#define</b> the
|
||||
macro <b>BOOST_MEM_FN_ENABLE_STDCALL</b> before including, directly or
|
||||
indirectly, <b><boost/mem_fn.hpp></b>.
|
||||
</p>
|
||||
<p>
|
||||
[Note: this is a non-portable extension. It is not part of the interface.]
|
||||
</p>
|
||||
<P>To use <B>mem_fn</B> with <B>__fastcall</B> member functions, <B>#define</B> the
|
||||
macro <B>BOOST_MEM_FN_ENABLE_FASTCALL</B> before including, directly or
|
||||
indirectly, <B><boost/mem_fn.hpp></B>.
|
||||
</P>
|
||||
<P>[Note: this is a non-portable extension. It is not part of the interface.]
|
||||
</P>
|
||||
<p>
|
||||
[Note: Some compilers provide only minimal support for the <b>__stdcall</b> keyword.]
|
||||
</p>
|
||||
|
185
mem_fn_fastcall_test.cpp
Normal file
185
mem_fn_fastcall_test.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// mem_fn_fastcall_test.cpp - a test for mem_fn.hpp + __fastcall
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#define BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#include <boost/mem_fn.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
struct X
|
||||
{
|
||||
mutable unsigned int hash;
|
||||
|
||||
X(): hash(0) {}
|
||||
|
||||
void __fastcall f0() { f1(17); }
|
||||
void __fastcall g0() const { g1(17); }
|
||||
|
||||
void __fastcall f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
|
||||
void __fastcall g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
|
||||
|
||||
void __fastcall f2(int a1, int a2) { f1(a1); f1(a2); }
|
||||
void __fastcall g2(int a1, int a2) const { g1(a1); g1(a2); }
|
||||
|
||||
void __fastcall f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
|
||||
void __fastcall g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
|
||||
|
||||
void __fastcall f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
|
||||
void __fastcall g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
|
||||
|
||||
void __fastcall f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
|
||||
void __fastcall g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
|
||||
|
||||
void __fastcall f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
|
||||
void __fastcall g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
|
||||
|
||||
void __fastcall f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
|
||||
void __fastcall g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
|
||||
|
||||
void __fastcall f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
|
||||
void __fastcall g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
|
||||
};
|
||||
|
||||
int detect_errors(bool x)
|
||||
{
|
||||
if(x)
|
||||
{
|
||||
std::cerr << "no errors detected.\n";
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "test failed.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mem_fn;
|
||||
|
||||
X x;
|
||||
|
||||
X const & rcx = x;
|
||||
X const * pcx = &x;
|
||||
|
||||
boost::shared_ptr<X> sp(new X);
|
||||
|
||||
mem_fn(&X::f0)(x);
|
||||
mem_fn(&X::f0)(&x);
|
||||
mem_fn(&X::f0)(sp);
|
||||
|
||||
mem_fn(&X::g0)(x);
|
||||
mem_fn(&X::g0)(rcx);
|
||||
mem_fn(&X::g0)(&x);
|
||||
mem_fn(&X::g0)(pcx);
|
||||
mem_fn(&X::g0)(sp);
|
||||
|
||||
mem_fn(&X::f1)(x, 1);
|
||||
mem_fn(&X::f1)(&x, 1);
|
||||
mem_fn(&X::f1)(sp, 1);
|
||||
|
||||
mem_fn(&X::g1)(x, 1);
|
||||
mem_fn(&X::g1)(rcx, 1);
|
||||
mem_fn(&X::g1)(&x, 1);
|
||||
mem_fn(&X::g1)(pcx, 1);
|
||||
mem_fn(&X::g1)(sp, 1);
|
||||
|
||||
mem_fn(&X::f2)(x, 1, 2);
|
||||
mem_fn(&X::f2)(&x, 1, 2);
|
||||
mem_fn(&X::f2)(sp, 1, 2);
|
||||
|
||||
mem_fn(&X::g2)(x, 1, 2);
|
||||
mem_fn(&X::g2)(rcx, 1, 2);
|
||||
mem_fn(&X::g2)(&x, 1, 2);
|
||||
mem_fn(&X::g2)(pcx, 1, 2);
|
||||
mem_fn(&X::g2)(sp, 1, 2);
|
||||
|
||||
mem_fn(&X::f3)(x, 1, 2, 3);
|
||||
mem_fn(&X::f3)(&x, 1, 2, 3);
|
||||
mem_fn(&X::f3)(sp, 1, 2, 3);
|
||||
|
||||
mem_fn(&X::g3)(x, 1, 2, 3);
|
||||
mem_fn(&X::g3)(rcx, 1, 2, 3);
|
||||
mem_fn(&X::g3)(&x, 1, 2, 3);
|
||||
mem_fn(&X::g3)(pcx, 1, 2, 3);
|
||||
mem_fn(&X::g3)(sp, 1, 2, 3);
|
||||
|
||||
mem_fn(&X::f4)(x, 1, 2, 3, 4);
|
||||
mem_fn(&X::f4)(&x, 1, 2, 3, 4);
|
||||
mem_fn(&X::f4)(sp, 1, 2, 3, 4);
|
||||
|
||||
mem_fn(&X::g4)(x, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(rcx, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(&x, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(pcx, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(sp, 1, 2, 3, 4);
|
||||
|
||||
mem_fn(&X::f5)(x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::f5)(&x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::f5)(sp, 1, 2, 3, 4, 5);
|
||||
|
||||
mem_fn(&X::g5)(x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(rcx, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(&x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(pcx, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(sp, 1, 2, 3, 4, 5);
|
||||
|
||||
mem_fn(&X::f6)(x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::f6)(&x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::f6)(sp, 1, 2, 3, 4, 5, 6);
|
||||
|
||||
mem_fn(&X::g6)(x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(rcx, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(&x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(pcx, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(sp, 1, 2, 3, 4, 5, 6);
|
||||
|
||||
mem_fn(&X::f7)(x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::f7)(&x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::f7)(sp, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
mem_fn(&X::g7)(x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(rcx, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(&x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(pcx, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(sp, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
mem_fn(&X::f8)(x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::f8)(&x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::f8)(sp, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
||||
mem_fn(&X::g8)(x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(rcx, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(&x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(pcx, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(sp, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
||||
return detect_errors(x.hash == 17610 && sp->hash == 2155);
|
||||
}
|
Reference in New Issue
Block a user