Full merge from trunk at revision 41356 of entire boost-root tree.

[SVN r41370]
This commit is contained in:
Beman Dawes
2007-11-25 18:38:02 +00:00
parent e04f655cc7
commit 291304b704
76 changed files with 8207 additions and 0 deletions

30
build/Jamfile Normal file
View File

@ -0,0 +1,30 @@
# (C) Copyright Tobias Schwinger
#
# Use modification and distribution are subject to the boost Software License,
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
# Generates preprocessed files with wave.
rule wave
{
Depends $1 : $2 ;
}
actions wave
{
$(BOOST_ROOT)/dist/bin/wave -S$(BOOST_ROOT) $(>) -o $(<)
}
make $(BOOST_ROOT)/libs/function_types/build/timestamps/arity_loops
: preprocess_arity_loops.cpp : wave
;
make $(BOOST_ROOT)/libs/function_types/build/timestamps/encoding
: preprocess_encoding.cpp : wave
;
make $(BOOST_ROOT)/libs/function_types/build/timestamps/cc_names
: preprocess_cc_names.cpp : wave
;

View File

@ -0,0 +1,88 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#if !defined(BOOST_FT_PREPROCESSING_MODE)
# ifndef __WAVE__
# error "Boost.Wave preprocessor required"
# endif
# include <boost/preprocessor/seq/cat.hpp>
# include <boost/preprocessor/stringize.hpp>
# if BOOST_PP_NIL // enable dependency scanning for dynamically included files
# include <boost/function_types/detail/encoding/def.hpp>
# include <boost/function_types/detail/components_impl/master.hpp>
# include <boost/function_types/detail/synthesize_impl/master.hpp>
# include <boost/function_types/detail/classifier_impl/master.hpp>
# endif
# pragma wave option(line: 0, preserve: 2)
timestamp file
# pragma wave option(output: null)
# define BOOST_FT_PREPROCESSING_MODE
# define BOOST_FT_HEADER \
BOOST_PP_SEQ_CAT((arity)(BOOST_FT_MAX_ARITY)(_)(BOOST_FT_mfp)).hpp
#define BOOST_FT_OUT_FILE \
BOOST_PP_STRINGIZE(../../../BOOST_FT_al_path/BOOST_FT_HEADER)
# define BOOST_FT_al_path boost/function_types/detail/components_impl
# include __FILE__
# undef BOOST_FT_al_path
# define BOOST_FT_al_path boost/function_types/detail/synthesize_impl
# include __FILE__
# undef BOOST_FT_al_path
# define BOOST_FT_al_path boost/function_types/detail/classifier_impl
# include __FILE__
# undef BOOST_FT_al_path
#elif !defined(BOOST_FT_mfp)
# define BOOST_FT_mfp 0
# include __FILE__
# undef BOOST_FT_mfp
# define BOOST_FT_mfp 1
# include __FILE__
# undef BOOST_FT_mfp
#elif !defined(BOOST_FT_MAX_ARITY)
# define BOOST_FT_FROM_ARITY 0
# define BOOST_FT_MAX_ARITY 10
# include __FILE__
# define BOOST_FT_FROM_ARITY 10
# define BOOST_FT_MAX_ARITY 20
# include __FILE__
# define BOOST_FT_FROM_ARITY 20
# define BOOST_FT_MAX_ARITY 30
# include __FILE__
# define BOOST_FT_FROM_ARITY 30
# define BOOST_FT_MAX_ARITY 40
# include __FILE__
# define BOOST_FT_FROM_ARITY 40
# define BOOST_FT_MAX_ARITY 50
# include __FILE__
#else
# pragma message(generating BOOST_FT_OUT_FILE)
# pragma wave option(preserve: 2, output: BOOST_FT_OUT_FILE)
# include <boost/function_types/detail/pp_arity_loop.hpp>
# undef BOOST_FT_MAX_ARITY
#endif

View File

@ -0,0 +1,27 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#ifndef __WAVE__
# error "Boost.Wave preprocessor required"
#endif
#pragma wave option(line: 0, preserve: 2)
timestamp file
#pragma wave option(output: null)
#define BOOST_FT_PREPROCESSING_MODE
#define BOOST_FT_OUT_FILE \
"../../../boost/function_types/detail/pp_cc_loop/preprocessed.hpp"
#pragma message(generating BOOST_FT_OUT_FILE)
#pragma wave option(output: BOOST_FT_OUT_FILE, preserve: 2)
#include <boost/function_types/detail/pp_cc_loop/master.hpp>
#pragma wave option(output: null)
#undef BOOST_FT_OUT_FILE

View File

@ -0,0 +1,45 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#ifndef __WAVE__
# error "Boost.Wave preprocessor required"
#endif
#pragma wave option(line: 0, preserve: 2)
timestamp file
#pragma wave option(output: null)
#define BOOST_FT_PREPROCESSING_MODE
#define BOOST_FT_OUT_FILE \
"../../../boost/function_types/detail/pp_tags/preprocessed.hpp"
#pragma message(generating BOOST_FT_OUT_FILE)
#pragma wave option(output: BOOST_FT_OUT_FILE, preserve: 2)
#include <boost/function_types/detail/pp_tags/master.hpp>
#pragma wave option(output: null)
#undef BOOST_FT_OUT_FILE
#define BOOST_FT_OUT_FILE \
"../../../boost/function_types/detail/pp_variate_loop/preprocessed.hpp"
#pragma message(generating BOOST_FT_OUT_FILE)
#pragma wave option(output: BOOST_FT_OUT_FILE, preserve: 2)
#include <boost/function_types/detail/pp_variate_loop/master.hpp>
#pragma wave option(output: null)
#undef BOOST_FT_OUT_FILE
#define BOOST_FT_OUT_FILE \
"../../../boost/function_types/detail/pp_retag_default_cc/preprocessed.hpp"
#pragma message(generating BOOST_FT_OUT_FILE)
#pragma wave option(output: BOOST_FT_OUT_FILE, preserve: 2)
#include <boost/function_types/detail/pp_retag_default_cc/master.hpp>
#pragma wave option(output: null)
#undef BOOST_FT_OUT_FILE

View File

@ -0,0 +1 @@
timestamp file

View File

@ -0,0 +1,2 @@
timestamp file

View File

@ -0,0 +1 @@
timestamp file

22
doc/Jamfile Normal file
View File

@ -0,0 +1,22 @@
# (C) Copyright Tobias Schwinger
#
# Use modification and distribution are subject to the boost Software License,
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
using quickbook ;
xml function_types : function_types.qbk ;
boostbook standalone
:
function_types
:
<xsl:param>boost.root=../../../..
<xsl:param>boost.libraries=../../../libraries.htm
<xsl:param>chunk.first.sections=1
<xsl:param>chunk.section.depth=2
<xsl:param>generate.section.toc.level=2
<xsl:param>toc.section.depth=1
<xsl:param>toc.max.depth=1
;

1104
doc/function_types.qbk Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> About Tag Types</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="prev" href="use_cases.html" title=" Use Cases">
<link rel="next" href="reference.html" title=" Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="use_cases.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functiontypes.about_tag_types"></a><a href="about_tag_types.html" title=" About Tag Types"> About Tag Types</a></h2></div></div></div>
<p>
Boost.FunctionTypes uses tag types to encode properties that are not types
per se, such as calling convention or whether a function is variadic or cv-
qualified.
</p>
<p>
These tags can be used to determine whether one property of a type has a particular
value.
</p>
<pre class="programlisting">
<span class="identifier">is_function</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">(...),</span> <span class="identifier">variadic</span><span class="special">&gt;::</span><span class="identifier">value</span> <span class="comment">// == true
</span><span class="identifier">is_function</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">()</span> <span class="special">,</span> <span class="identifier">variadic</span><span class="special">&gt;::</span><span class="identifier">value</span> <span class="comment">// == false
</span></pre>
<p>
A compound property tag describes a combination of possible values of different
properties. The type <code class="literal">components&lt;F&gt;</code>, where <code class="literal">F</code>
is a callable builtin type, is a compound property tag that describes <code class="literal">F</code>.
The <code class="literal">tag</code> class template can be used to combine property tags.
</p>
<pre class="programlisting">
<span class="identifier">tag</span><span class="special">&lt;</span><span class="identifier">non_const</span><span class="special">,</span><span class="identifier">default_cc</span><span class="special">&gt;</span> <span class="comment">// combination of two properties
</span></pre>
<p>
When several values for the same property are specified in <code class="literal">tag</code>'s
argument list, only the rightmost one is used; others are ignored.
</p>
<pre class="programlisting">
<span class="identifier">tag</span><span class="special">&lt;</span><span class="identifier">components</span><span class="special">&lt;</span><span class="identifier">F</span><span class="special">&gt;,</span> <span class="identifier">default_cc</span><span class="special">&gt;</span> <span class="comment">// overrides F's calling convention property
</span></pre>
<p>
When compound property tag is specified to analyse a type, all of its component
properties must match.
</p>
<pre class="programlisting">
<span class="identifier">is_member_function_pointer</span><span class="special">&lt;</span> <span class="identifier">F</span><span class="special">,</span> <span class="identifier">tag</span><span class="special">&lt;</span><span class="identifier">const_qualified</span><span class="special">,</span><span class="identifier">default_cc</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">value</span>
<span class="comment">// true for
</span><span class="comment">// F = void(a_class::*)() const
</span><span class="comment">// false for
</span><span class="comment">// F = void(a_class::*)()
</span><span class="comment">// F = void(__fastcall a_class::*)() const
</span></pre>
<p>
Default values are selected for properties not specified by the tag in the
context of type synthesis.
</p>
<pre class="programlisting">
<span class="comment">// given S = mpl::vector&lt;int,a_class const &amp;&gt;
</span>
<span class="identifier">member_function_pointer</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="comment">// is int (a_class::*)() const
</span><span class="comment">// note: the cv-qualification is picked based on the class type,
</span><span class="comment">// a nonvariadic signature and the default calling convention
</span><span class="comment">// are used
</span>
<span class="identifier">member_function_pointer</span><span class="special">&lt;</span><span class="identifier">S</span><span class="special">,</span><span class="identifier">non_const</span><span class="special">&gt;::</span><span class="identifier">type</span> <span class="comment">// is int (a_class::*)()
</span><span class="comment">// no const qualification, as explicitly specified by the tag type
</span></pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="use_cases.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="reference.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,85 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Acknowledgements</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="prev" href="rationale.html" title=" Rationale">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="rationale.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functiontypes.acknowledgements"></a><a href="acknowledgements.html" title=" Acknowledgements"> Acknowledgements</a></h2></div></div></div>
<p>
Thanks go to the following people for supporting the development of this library
in one or the other way:
</p>
<div class="itemizedlist"><ul type="disc">
<li>
David Abrahams
</li>
<li>
Tom Brinkman
</li>
<li>
Aleksey Gurtovoy
</li>
<li>
Jody Hagins
</li>
<li>
Hartmut Kaiser
</li>
<li>
Andy Little
</li>
<li>
John Maddock
</li>
<li>
Paul Mensonides
</li>
<li>
Alexander Nasonov
</li>
<li>
Richard Smith
</li>
<li>
Rob Stewart
</li>
<li>
Jonathan Turkanis
</li>
<li>
Pavel Vozenilek
</li>
<li>
Steven Watanabe
</li>
</ul></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="rationale.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,94 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Introduction</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="prev" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="next" href="use_cases.html" title=" Use Cases">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="use_cases.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functiontypes.introduction"></a><a href="introduction.html" title=" Introduction"> Introduction</a></h2></div></div></div>
<p>
Boost.FunctionTypes provides functionality to classify, decompose and synthesize
function, function pointer, function reference and pointer to member types.
</p>
<p>
We collectively refer to these types as <span class="emphasis"><em>callable builtin</em></span>
types.
</p>
<p>
In particular, the library can be used to:
</p>
<div class="itemizedlist"><ul type="disc">
<li>
test whether a type is a specific callable, builtin type,
</li>
<li>
extract all component properties from callable, builtin types, and
</li>
<li>
create callable, builtin types from specified properties.
</li>
</ul></div>
<p>
The library is designed to work well with other Boost libraries and uses well-accepted
concepts introduced by Boost and TR1.
</p>
<p>
Templates that encapsulate boolean or numeric properties define a static member
constant called <code class="literal">value</code>.
</p>
<pre class="programlisting">
<a href="reference/classification.html#boost_functiontypes.reference.classification.is_function_pointer" title="
is_function_pointer">is_function_pointer</a><span class="special">&lt;</span> <span class="keyword">bool</span><span class="special">(*)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">&gt;::</span><span class="identifier">value</span> <span class="comment">// == true
</span>
<a href="reference/decomposition.html#boost_functiontypes.reference.decomposition.function_arity" title="
function_arity">function_arity</a><span class="special">&lt;</span> <span class="keyword">bool</span><span class="special">(*)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">&gt;::</span><span class="identifier">value</span> <span class="comment">// == 1
</span></pre>
<p>
Templates that encapsulate properties that are single types contain a type
member called <code class="literal">type</code>.
</p>
<pre class="programlisting">
<a href="reference/synthesis.html#boost_functiontypes.reference.synthesis.function_type" title="
function_type">function_type</a><span class="special">&lt;</span> <span class="identifier">mpl</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">,</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="comment">// is bool(int)
</span>
<a href="reference/decomposition.html#boost_functiontypes.reference.decomposition.result_type" title="
result_type">result_type</a><span class="special">&lt;</span> <span class="keyword">bool</span><span class="special">(&amp;)(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="comment">// is bool
</span></pre>
<p>
Templates that encapsulate properties that are type lists model an MPL-compatible
type sequence.
</p>
<pre class="programlisting">
<a href="reference/decomposition.html#boost_functiontypes.reference.decomposition.parameter_types" title="
parameter_types">parameter_types</a><span class="special">&lt;</span> <span class="keyword">bool</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span> <span class="special">&gt;</span> <span class="comment">// models an MPL sequence
</span></pre>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../index.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="use_cases.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,149 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Rationale</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="prev" href="reference/macros.html" title=" Macros">
<link rel="next" href="acknowledgements.html" title=" Acknowledgements">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="reference/macros.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functiontypes.rationale"></a><a href="rationale.html" title=" Rationale"> Rationale</a></h2></div></div></div>
<a name="boost_functiontypes.rationale.error_handling_rationale"></a><h3>
<a name="id932131"></a>
<a href="rationale.html#boost_functiontypes.rationale.error_handling_rationale">Error
handling rationale</a>
</h3>
<p>
The library does not define the required members of class templates in case
of an error. This technique causes the compiler to stop displaying diagnostics
in client code, at the point where the error actually is, instead of tracing
template instantiations into the implementation of the library.
</p>
<p>
The library's components have limited error conditions, so problematic input
can be spotted easily.
</p>
<a name="boost_functiontypes.rationale.why_mpl_sequences_"></a><h3>
<a name="id932169"></a>
<a href="rationale.html#boost_functiontypes.rationale.why_mpl_sequences_">Why MPL Sequences?</a>
</h3>
<p>
MPL provides algorithms on Sequences, so transformations (such as turning by-value
parameter types into const references for optimized forwarding or computing
a signature to specialize <a href="../../../../function/index.html" target="_top"><code class="literal">boost::function</code></a>
after applying <a href="../../../../bind/index.html" target="_top"><code class="literal">boost::bind</code></a>)
can be expressed more easily. The MPL Sequence concept is compatible with several
other Boost libraries (most importantly <a href="../../../../fusion/index.html" target="_top">Fusion</a>),
so another reason is interoperability.
</p>
<a name="boost_functiontypes.rationale.pointer_to_member_object_types"></a><h3>
<a name="id932226"></a>
<a href="rationale.html#boost_functiontypes.rationale.pointer_to_member_object_types">Pointer
to member object types</a>
</h3>
<p>
Despite their syntax, pointer to member object types can be seen as dereferencing
functionals.
</p>
<a name="boost_functiontypes.rationale.the_classtransform_template_parameter"></a><h3>
<a name="id932258"></a>
<a href="rationale.html#boost_functiontypes.rationale.the_classtransform_template_parameter">The
ClassTransform template parameter</a>
</h3>
<p>
<code class="literal">This</code>-pointer, <code class="literal">this</code>-reference or just
the object (or maybe even a smart pointer to the object) plus adjustments of
cv-qualification - all these cases have their place, somewhere and there is
no single best answer.
</p>
<p>
Special treatment of the class type within the sequence can significantly complicate
client code. A custom <code class="literal">ClassTransform</code> argument allows the
client to adjust the class type before the sequence is formed and then treat
all parameters uniformly.
</p>
<a name="boost_functiontypes.rationale.why_tag_types_"></a><h3>
<a name="id932313"></a>
<a href="rationale.html#boost_functiontypes.rationale.why_tag_types_">Why tag types?</a>
</h3>
<p>
Let's consider the alternatives.
</p>
<p>
The first one is just using more templates so every property has to be asked
for explicitly. This approach results in more complicated client code if more
than one propery has to be checked and in a exponentially larger library interface.
</p>
<p>
The second alternative is having the client pass in bit patterns via non-type
template parameters. The logic has to be performed by the client and there
are much more error conditions. Further, class templates with non-type template
parameters do not work within MPL lambda expressions and can cause problems
with older compilers.
</p>
<a name="boost_functiontypes.rationale.is_it_safe_to_have_the_synthesis_templates_take_a_callable__builtin_type_or_an_mpl_sequence_as_the_first_template_argument_"></a><h3>
<a name="id932364"></a>
<a href="rationale.html#boost_functiontypes.rationale.is_it_safe_to_have_the_synthesis_templates_take_a_callable__builtin_type_or_an_mpl_sequence_as_the_first_template_argument_">Is
it safe to have the synthesis templates take a callable builtin type or an
MPL sequence as the first template argument?</a>
</h3>
<p>
Yes, but it isn't immediately obvious as the set of possible MPL sequences
isn't inherently disjoint from the set of callable builtin types.
</p>
<p>
However, any attempt to make a builtin type work as an MPL sequence is a bad
idea, because builtin types are accessible before the headers that make the
type a sequence have been included, which can easily violate the ODR.
</p>
<a name="boost_functiontypes.rationale.why_does_the_hidden__literal_this__literal__parameter_count_for_the__function_arity_of_member_functions_"></a><h3>
<a name="id932412"></a>
<a href="rationale.html#boost_functiontypes.rationale.why_does_the_hidden__literal_this__literal__parameter_count_for_the__function_arity_of_member_functions_">Why
does the hidden <code class="literal">this</code> parameter count for the function arity
of member functions?</a>
</h3>
<p>
It was found preferable that the following condition holds:
</p>
<pre class="programlisting">
<span class="identifier">mpl</span><span class="special">::</span><span class="identifier">size</span><span class="special">&lt;</span> <a href="reference/decomposition.html#boost_functiontypes.reference.decomposition.parameter_types" title="
parameter_types">parameter_types</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&gt;::</span><span class="identifier">value</span> <span class="special">==</span> <a href="reference/decomposition.html#boost_functiontypes.reference.decomposition.function_arity" title="
function_arity">function_arity</a><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value</span>
</pre>
<a name="boost_functiontypes.rationale.why_ignore_top_level_cv_qualifiers_on_pointers_"></a><h3>
<a name="id932539"></a>
<a href="rationale.html#boost_functiontypes.rationale.why_ignore_top_level_cv_qualifiers_on_pointers_">Why
ignore top-level cv-qualifiers on pointers?</a>
</h3>
<p>
A cv-qualified pointer is still a pointer. It usually doesn't matter and even
if it does, it's a job for <a href="../../../../type_traits/index.html" target="_top">Boost.TypeTraits</a>.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="reference/macros.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgements.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,49 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Reference</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="prev" href="about_tag_types.html" title=" About Tag Types">
<link rel="next" href="reference/classification.html" title=" Class
templates for type classification">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="about_tag_types.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="reference/classification.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functiontypes.reference"></a><a href="reference.html" title=" Reference"> Reference</a></h2></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="reference/classification.html"> Class
templates for type classification</a></span></dt>
<dt><span class="section"><a href="reference/decomposition.html"> Class templates
for type decomposition</a></span></dt>
<dt><span class="section"><a href="reference/synthesis.html"> Class templates
for type synthesis</a></span></dt>
<dt><span class="section"><a href="reference/tag_types.html"> Tag Types</a></span></dt>
<dt><span class="section"><a href="reference/macros.html"> Macros</a></span></dt>
</dl></div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="about_tag_types.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="reference/classification.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,407 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Class
templates for type classification</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../reference.html" title=" Reference">
<link rel="prev" href="../reference.html" title=" Reference">
<link rel="next" href="decomposition.html" title=" Class templates
for type decomposition">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../reference.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="decomposition.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functiontypes.reference.classification"></a><a href="classification.html" title=" Class
templates for type classification"> Class
templates for type classification</a></h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_function">
is_function</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_function_pointer">
is_function_pointer</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_function_reference">
is_function_reference</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_member_pointer">
is_member_pointer</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_member_object_pointer">
is_member_object_pointer</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_member_function_pointer">
is_member_function_pointer</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_callable_builtin">
is_callable_builtin</a></span></dt>
<dt><span class="section"><a href="classification.html#boost_functiontypes.reference.classification.is_nonmember_callable_builtin">
is_nonmember_callable_builtin</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_function"></a><a href="classification.html#boost_functiontypes.reference.classification.is_function" title="
is_function">
is_function</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_function</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_function</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_function&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value as <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_function&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a function, possibly with additional
properties as specified by a property tag.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_function_pointer"></a><a href="classification.html#boost_functiontypes.reference.classification.is_function_pointer" title="
is_function_pointer">
is_function_pointer</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_function_pointer</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_function_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_function_pointer&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value <a href="../../../../../mpl/index.html" target="_top">MPL</a> -
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_function_pointer&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a function pointer, possibly with additional
properties as specified by a property tag.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_function_reference"></a><a href="classification.html#boost_functiontypes.reference.classification.is_function_reference" title="
is_function_reference">
is_function_reference</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_function_reference</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_function_reference</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_function_reference&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value <a href="../../../../../mpl/index.html" target="_top">MPL</a> -
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_function_reference&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a function reference, possibly with
additional properties as specified by a property tag.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_member_pointer"></a><a href="classification.html#boost_functiontypes.reference.classification.is_member_pointer" title="
is_member_pointer">
is_member_pointer</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_member_pointer</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_member_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_member_pointer&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value <a href="../../../../../mpl/index.html" target="_top">MPL</a> -
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_member_pointer&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a pointer to member (object or function)
type, possibly with additional properties as specified by a property tag.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_member_object_pointer"></a><a href="classification.html#boost_functiontypes.reference.classification.is_member_object_pointer" title="
is_member_object_pointer">
is_member_object_pointer</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_member_object_pointer</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_member_object_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">is_member_object_pointer&lt;T&gt;</code></span></dt>
<dd><p>
Predicate value <a href="../../../../../mpl/index.html" target="_top">MPL</a> -
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_member_object_pointer&lt;T&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a pointer to member object type.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_member_function_pointer"></a><a href="classification.html#boost_functiontypes.reference.classification.is_member_function_pointer" title="
is_member_function_pointer">
is_member_function_pointer</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_member_function_pointer</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_member_function_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_member_function_pointer&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value <a href="../../../../../mpl/index.html" target="_top">MPL</a> -
<a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_member_function_pointer&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a member function pointer, possibly
with additional properties as specified by a property tag.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_callable_builtin"></a><a href="classification.html#boost_functiontypes.reference.classification.is_callable_builtin" title="
is_callable_builtin">
is_callable_builtin</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_callable_builtin</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_callable_builtin</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_callable_builtin&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value as <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_callable_builtin&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a callable builtin, possibly with additional
properties as specified by a property tag.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.classification.is_nonmember_callable_builtin"></a><a href="classification.html#boost_functiontypes.reference.classification.is_nonmember_callable_builtin" title="
is_nonmember_callable_builtin">
is_nonmember_callable_builtin</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">is_nonmember_callable_builtin</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">is_nonmember_callable_builtin</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties required for a positive result
</p></dd>
<dt><span class="term"><code class="literal">is_nonmember_callable_builtin&lt;T,Tag&gt;</code></span></dt>
<dd><p>
Predicate value as <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">is_nonmember_callable_builtin&lt;T,Tag&gt;::value</code></span></dt>
<dd><p>
Constant boolean value
</p></dd>
</dl>
</div>
<p>
Determines whether a given type is a callable builtin that is not a member
function pointer, possibly with additional properties as specified by a
property tag.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../reference.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="decomposition.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,233 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Class templates
for type decomposition</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../reference.html" title=" Reference">
<link rel="prev" href="classification.html" title=" Class
templates for type classification">
<link rel="next" href="synthesis.html" title=" Class templates
for type synthesis">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="classification.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="synthesis.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functiontypes.reference.decomposition"></a><a href="decomposition.html" title=" Class templates
for type decomposition"> Class templates
for type decomposition</a></h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="decomposition.html#boost_functiontypes.reference.decomposition.result_type">
result_type</a></span></dt>
<dt><span class="section"><a href="decomposition.html#boost_functiontypes.reference.decomposition.parameter_types">
parameter_types</a></span></dt>
<dt><span class="section"><a href="decomposition.html#boost_functiontypes.reference.decomposition.function_arity">
function_arity</a></span></dt>
<dt><span class="section"><a href="decomposition.html#boost_functiontypes.reference.decomposition.components">
components</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.decomposition.result_type"></a><a href="decomposition.html#boost_functiontypes.reference.decomposition.result_type" title="
result_type">
result_type</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">result_type</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">result_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">F</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">result_type&lt;F&gt;::type</code></span></dt>
<dd><p>
Result type of <code class="literal">F</code>
</p></dd>
</dl>
</div>
<p>
Extracts the result type of a callable, builtin type.
</p>
<p>
If <code class="literal">F</code> is no callable, builtin type, any attempt to access
the <code class="literal">type</code> member results in a compile error.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.decomposition.parameter_types"></a><a href="decomposition.html#boost_functiontypes.reference.decomposition.parameter_types" title="
parameter_types">
parameter_types</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ClassTransform</span> <span class="special">=</span> <span class="identifier">add_reference</span><span class="special">&lt;</span><span class="identifier">_</span><span class="special">&gt;</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">parameter_types</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">parameter_types</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">F</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">ClassTransform</code></span></dt>
<dd><p>
<a href="../../../../../mpl/index.html" target="_top">MPL</a> - <a href="../../../../../mpl/doc/refmanual/lambda-expression.html" target="_top">Lambda
Expression</a> to transform the class type if <code class="literal">F</code>
is a member function pointer
</p></dd>
<dt><span class="term"><code class="literal">parameter_types&lt;F,ClassTransform&gt;</code></span></dt>
<dd><p>
<a href="../../../../../mpl/index.html" target="_top">MPL</a> - <a href="../../../../../mpl/doc/refmanual/front-extensible-sequence.html" target="_top">Front</a>
/ <a href="../../../../../mpl/doc/refmanual/back-extensible-sequence.html" target="_top">Back
</a><a href="../../../../../mpl/doc/refmanual/extensible-sequence.html" target="_top">Extensible
</a><a href="../../../../../mpl/doc/refmanual/random-access-sequence.html" target="_top">Random
Access Sequence</a> of parameter types
</p></dd>
</dl>
</div>
<p>
Extracts the parameter types of a callable, builtin type.
</p>
<p>
If <code class="literal">F</code> is no callable, builtin type, any attempt to access
the sequence results in a compile error.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.decomposition.function_arity"></a><a href="decomposition.html#boost_functiontypes.reference.decomposition.function_arity" title="
function_arity">
function_arity</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">function_arity</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">function_arity</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">F</code></span></dt>
<dd><p>
Callable builtin type
</p></dd>
<dt><span class="term"><code class="literal">function_arity&lt;F&gt;</code></span></dt>
<dd><p>
Function arity as <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/integral-constant.html" target="_top">Integral
Constant</a>
</p></dd>
<dt><span class="term"><code class="literal">function_arity&lt;F&gt;::value</code></span></dt>
<dd><p>
Constant value of the function arity
</p></dd>
</dl>
</div>
<p>
Extracts the function arity, that is the number of parameters. The hidden
<code class="literal">this</code> of member function pointers counts, in other words
the arity value is always greater than or equal to one if <code class="literal">F</code>
is a member function pointer.
</p>
<p>
If <code class="literal">F</code> is no callable, builtin type, any attempt to access
the value results in a compile error.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.decomposition.components"></a><a href="decomposition.html#boost_functiontypes.reference.decomposition.components" title="
components">
components</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">ClassTransform</span> <span class="special">=</span> <span class="identifier">add_reference</span><span class="special">&lt;</span><span class="identifier">_</span><span class="special">&gt;</span> <span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">components</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">components</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">T</code></span></dt>
<dd><p>
Type to analyze
</p></dd>
<dt><span class="term"><code class="literal">ClassTransform</code></span></dt>
<dd><p>
<a href="../../../../../mpl/index.html" target="_top">MPL</a> - <a href="../../../../../mpl/doc/refmanual/lambda-expression.html" target="_top">Lambda
Expression</a> to transform the class type if <code class="literal">T</code>
is a member function pointer
</p></dd>
<dt><span class="term"><code class="literal">components&lt;T,ClassTransform&gt;</code></span></dt>
<dd><p>
<a href="../../../../../mpl/index.html" target="_top">MPL</a> - <a href="../../../../../mpl/doc/refmanual/front-extensible-sequence.html" target="_top">Front</a>
/ <a href="../../../../../mpl/doc/refmanual/back-extensible-sequence.html" target="_top">Back
</a><a href="../../../../../mpl/doc/refmanual/extensible-sequence.html" target="_top">Extensible
</a><a href="../../../../../mpl/doc/refmanual/random-access-sequence.html" target="_top">Random
Access Sequence</a> of all component types and property tag
</p></dd>
<dt><span class="term"><code class="literal">components&lt;T,ClassTransform&gt;::types</code></span></dt>
<dd><p>
Decorated MPL Sequence, exposed for optimization
</p></dd>
</dl>
</div>
<p>
Extracts all properties of a callable builtin type, that is the result
type, followed by the parameter types (including the type of <code class="literal">this</code>
for member function pointers).
</p>
<p>
If <code class="literal">T</code> is no callable builtin type, the component types
are an empty sequence and the Tag's meaning is equivalent to the <code class="literal"><a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a></code>.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="classification.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="synthesis.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,246 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Macros</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../reference.html" title=" Reference">
<link rel="prev" href="tag_types.html" title=" Tag Types">
<link rel="next" href="../rationale.html" title=" Rationale">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tag_types.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="../rationale.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functiontypes.reference.macros"></a><a href="macros.html" title=" Macros"> Macros</a></h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_MAX_ARITY">
BOOST_FT_MAX_ARITY</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES">
BOOST_FT_CC_NAMES</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC">
BOOST_FT_CC_*</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_COMMON_X86_CCs">
BOOST_FT_COMMON_X86_CCs</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_SYNTAX">
BOOST_FT_SYNTAX</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_NULLARY_PARAM">
BOOST_FT_NULLARY_PARAM</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_NO_CV_FUNC_SUPPORT">
BOOST_FT_NO_CV_FUNC_SUPPORT</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_PREPROCESSING_MODE">
BOOST_FT_PREPROCESSING_MODE</a></span></dt>
<dt><span class="section"><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_PREPROCESSING">
BOOST_FT_CC_PREPROCESSING</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_MAX_ARITY"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_MAX_ARITY" title="
BOOST_FT_MAX_ARITY">
BOOST_FT_MAX_ARITY</a></h4></div></div></div>
<p>
Expands to a numeric value that describes the maximum function arity supported
by the library.
</p>
<p>
Defaults to 20 if not explicitly defined by the user before inclusion of
the first library header.
</p>
</div>
<p>
<span class="bold"><strong>The following macros do not need to be defined, unless
to configure the library to work with a compiler and/or calling convention
not covered by the auto-detection mechanism in <code class="literal">boost/function_types/config/compiler.hpp</code>.</strong></span>
</p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES" title="
BOOST_FT_CC_NAMES">
BOOST_FT_CC_NAMES</a></h4></div></div></div>
<p>
Expands to a <a href="../../../../../preprocessor/doc/data/sequences.html" target="_top">sequence</a>
of ternary <a href="../../../../../preprocessor/doc/data/tuples.html" target="_top">tuples</a>
(these data types are defined in the <a href="../../../../../preprocessor/doc/index.html" target="_top">documentation
of the Boost Preprocessor library</a>). Each sequence element describes
one calling convention specifier. The first element in each tuple is the
macro suffix for <a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC" title="
BOOST_FT_CC_*"><code class="literal">BOOST_FT_CC_*</code></a>,
the second element is the name of the tag that describes the calling convention
and the third is the name of the specifier. The specifier is allowed to
be an empty string, so the third tuple element is either <a href="../../../../../preprocessor/doc/ref/empty.html" target="_top"><code class="literal">BOOST_PP_EMPTY</code></a>
or <a href="../../../../../preprocessor/doc/ref/identity.html" target="_top"><code class="literal">BOOST_PP_IDENTITY</code></a><code class="literal">(<span class="emphasis"><em>name</em></span>)</code>.
</p>
<p>
Define this macro to extend the set of possible names for custom calling
conventions. The macro expands to nothing by default.
</p>
<p>
The following names are predefined by the library and must not occur in
the definition of <code class="literal">BOOST_FT_CC_NAMES</code>:
</p>
<pre class="programlisting">
<span class="preprocessor">#define</span> <span class="identifier">BOOST_FT_BUILTIN_CC_NAMES</span> <span class="special">\</span>
<span class="special">((</span> <span class="identifier">IMPLICIT</span> <span class="special">,</span> <span class="identifier">implicit_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_EMPTY</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">CDECL</span> <span class="special">,</span> <span class="identifier">cdecl_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_IDENTITY</span><span class="special">(</span><span class="identifier">__cdecl</span> <span class="special">)</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">STDCALL</span> <span class="special">,</span> <span class="identifier">stdcall_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_IDENTITY</span><span class="special">(</span><span class="identifier">__stdcall</span> <span class="special">)</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">PASCAL</span> <span class="special">,</span> <span class="identifier">pascal_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_IDENTITY</span><span class="special">(</span><span class="identifier">pascal</span> <span class="special">)</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">FASTCALL</span> <span class="special">,</span> <span class="identifier">fastcall_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_IDENTITY</span><span class="special">(</span><span class="identifier">__fastcall</span><span class="special">)</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">CLRCALL</span> <span class="special">,</span> <span class="identifier">clrcall_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_IDENTITY</span><span class="special">(</span><span class="identifier">__clrcall</span> <span class="special">)</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">THISCALL</span> <span class="special">,</span> <span class="identifier">thiscall_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_IDENTITY</span><span class="special">(</span><span class="identifier">__thiscall</span><span class="special">)</span> <span class="special">))\</span>
<span class="special">((</span> <span class="identifier">IMPLICIT_THISCALL</span> <span class="special">,</span> <span class="identifier">thiscall_cc</span> <span class="special">,</span> <span class="identifier">BOOST_PP_EMPTY</span> <span class="special">))</span>
<span class="comment">// Don't get confused by the last line, here (thiscall can't be specified
</span><span class="comment">// explicitly prior to MSVC 8).
</span></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_CC"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC" title="
BOOST_FT_CC_*">
BOOST_FT_CC_*</a></h4></div></div></div>
<p>
Enables a specific calling convention. * dentoes the macro suffix, as defined
by <a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES" title="
BOOST_FT_CC_NAMES"><code class="literal">BOOST_FT_CC_NAMES</code></a>
or <a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES" title="
BOOST_FT_CC_NAMES"><code class="literal">BOOST_FT_BUILTIN_CC_NAMES</code></a>.
</p>
<p>
The macro expands to a list of restrictions, separated by the <code class="literal">|</code>
character. Possible items are:
</p>
<div class="itemizedlist"><ul type="disc">
<li>
callable_builtin
</li>
<li>
member
</li>
<li>
non_member
</li>
<li>
variadic
</li>
<li>
non_variadic
</li>
</ul></div>
<p>
If no such macro is defined for a particular calling convention, it is
disabled. Example:
</p>
<pre class="programlisting">
<span class="preprocessor">#define</span> <span class="identifier">BOOST_FT_CC_STDCALL</span> <span class="identifier">non_variadic</span><span class="special">|</span><span class="identifier">callable_builtin</span>
<span class="comment">// enables stdcall calling convention for all non-variadic,
</span><span class="comment">// callable, builtin types
</span></pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_COMMON_X86_CCs"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_COMMON_X86_CCs" title="
BOOST_FT_COMMON_X86_CCs">
BOOST_FT_COMMON_X86_CCs</a></h4></div></div></div>
<p>
Defining this macro causes the following macros to be defined, if not defined
already:
</p>
<pre class="programlisting">
<span class="preprocessor">#define</span> <span class="identifier">BOOST_FT_CC_CDECL</span> <span class="identifier">BOOST_FT_COMMON_X86_CCs</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_FT_CC_STDCALL</span> <span class="identifier">non_variadic</span><span class="special">|</span><span class="identifier">BOOST_FT_COMMON_X86_CCs</span>
<span class="preprocessor">#define</span> <span class="identifier">BOOST_FT_CC_FASTCALL</span> <span class="identifier">non_variadic</span><span class="special">|</span><span class="identifier">BOOST_FT_COMMON_X86_CCs</span>
</pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_SYNTAX"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_SYNTAX" title="
BOOST_FT_SYNTAX">
BOOST_FT_SYNTAX</a></h4></div></div></div>
<p>
This macro allows to change the syntax of callable builtin types. It is
useful to handle the compiler specific placement of the calling convention
specifier.
</p>
<p>
The default definition is as follows:
</p>
<pre class="programlisting">
<span class="preprocessor">#define</span> <span class="identifier">BOOST_FT_SYNTAX</span><span class="special">(</span><span class="identifier">result</span><span class="special">,</span><span class="identifier">lparen</span><span class="special">,</span><span class="identifier">cc_spec</span><span class="special">,</span><span class="identifier">type_mod</span><span class="special">,</span><span class="identifier">name</span><span class="special">,</span><span class="identifier">rparen</span><span class="special">)</span> <span class="special">\</span>
<span class="identifier">result</span><span class="special">()</span> <span class="identifier">lparen</span><span class="special">()</span> <span class="identifier">cc_spec</span><span class="special">()</span> <span class="identifier">type_mod</span><span class="special">()</span> <span class="identifier">name</span><span class="special">()</span> <span class="identifier">rparen</span><span class="special">()</span>
</pre>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_NULLARY_PARAM"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_NULLARY_PARAM" title="
BOOST_FT_NULLARY_PARAM">
BOOST_FT_NULLARY_PARAM</a></h4></div></div></div>
<p>
Set to <code class="literal">void</code> for compilers that insist on a <code class="literal">void</code>
parameter for nullary function types, empty by default.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_NO_CV_FUNC_SUPPORT"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_NO_CV_FUNC_SUPPORT" title="
BOOST_FT_NO_CV_FUNC_SUPPORT">
BOOST_FT_NO_CV_FUNC_SUPPORT</a></h4></div></div></div>
<p>
Disables support for cv-qualified function types. Cv-qualified function
types are illegal by the current standard version, but there is a pending
defect report on that issue. It defaults to <code class="literal">1</code> until
the standard changes, setting this macro to <code class="literal">0</code> may not
work.
</p>
</div>
<p>
<span class="bold"><strong>The following macros are useful for testing when changing
the source code of the library.</strong></span>
</p>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_PREPROCESSING_MODE"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_PREPROCESSING_MODE" title="
BOOST_FT_PREPROCESSING_MODE">
BOOST_FT_PREPROCESSING_MODE</a></h4></div></div></div>
<p>
Makes the compiler preprocess as much as possible of the library code (rather
than loading already-preprocessed header files) if defined.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.macros.BOOST_FT_CC_PREPROCESSING"></a><a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_PREPROCESSING" title="
BOOST_FT_CC_PREPROCESSING">
BOOST_FT_CC_PREPROCESSING</a></h4></div></div></div>
<p>
Makes the compiler preprocess the loop over possible names for custom calling
conventions (rather than loading an already-preprocessed header file) if
defined.
</p>
<p>
This macro is defined automatically if <a href="macros.html#boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES" title="
BOOST_FT_CC_NAMES"><code class="literal">BOOST_FT_CC_NAMES</code></a>
has been defined.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tag_types.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="../rationale.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,230 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Class templates
for type synthesis</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../reference.html" title=" Reference">
<link rel="prev" href="decomposition.html" title=" Class templates
for type decomposition">
<link rel="next" href="tag_types.html" title=" Tag Types">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="decomposition.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="tag_types.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functiontypes.reference.synthesis"></a><a href="synthesis.html" title=" Class templates
for type synthesis"> Class templates
for type synthesis</a></h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="synthesis.html#boost_functiontypes.reference.synthesis.function_type">
function_type</a></span></dt>
<dt><span class="section"><a href="synthesis.html#boost_functiontypes.reference.synthesis.function_pointer">
function_pointer</a></span></dt>
<dt><span class="section"><a href="synthesis.html#boost_functiontypes.reference.synthesis.function_reference">
function_reference</a></span></dt>
<dt><span class="section"><a href="synthesis.html#boost_functiontypes.reference.synthesis.member_function_pointer">
member_function_pointer</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.synthesis.function_type"></a><a href="synthesis.html#boost_functiontypes.reference.synthesis.function_type" title="
function_type">
function_type</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Types</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">function_type</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">function_type</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">Types</code></span></dt>
<dd><p>
Component types in form of an <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/forward-sequence.html" target="_top">Forward
Sequence</a> or another callable, builtin type
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties
</p></dd>
<dt><span class="term"><code class="literal">function_type&lt;Types,Tag&gt;::type</code></span></dt>
<dd><p>
Synthesized type
</p></dd>
</dl>
</div>
<p>
Synthesizes a function type from given properties.
</p>
<p>
If the template parameters do not describe a valid type, any attempt to
access the <code class="literal">type</code> member will result in a compile error.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.synthesis.function_pointer"></a><a href="synthesis.html#boost_functiontypes.reference.synthesis.function_pointer" title="
function_pointer">
function_pointer</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Types</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">function_pointer</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">function_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">Types</code></span></dt>
<dd><p>
Component types in form of an <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/forward-sequence.html" target="_top">Forward
Sequence</a> or another callable, builtin type
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties
</p></dd>
<dt><span class="term"><code class="literal">function_pointer&lt;Types,Tag&gt;::type</code></span></dt>
<dd><p>
Synthesized type
</p></dd>
</dl>
</div>
<p>
Synthesizes a function pointer type from given properties.
</p>
<p>
If the template parameters do not describe a valid type, any attempt to
access the <code class="literal">type</code> member will result in a compile error.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.synthesis.function_reference"></a><a href="synthesis.html#boost_functiontypes.reference.synthesis.function_reference" title="
function_reference">
function_reference</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Types</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">function_reference</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">function_reference</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">Types</code></span></dt>
<dd><p>
Component types in form of an <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/forward-sequence.html" target="_top">Forward
Sequence</a> or another callable, builtin type
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties
</p></dd>
<dt><span class="term"><code class="literal">function_reference&lt;Types,Tag&gt;::type</code></span></dt>
<dd><p>
Synthesized type
</p></dd>
</dl>
</div>
<p>
Synthesizes a function reference type from given properties.
</p>
<p>
If the template parameters do not describe a valid type, any attempt to
access the <code class="literal">type</code> member will result in a compile error.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.synthesis.member_function_pointer"></a><a href="synthesis.html#boost_functiontypes.reference.synthesis.member_function_pointer" title="
member_function_pointer">
member_function_pointer</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Types</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Tag</span> <span class="special">=</span> <a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">null_tag</a><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">member_function_pointer</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">member_function_pointer</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">Types</code></span></dt>
<dd><p>
Component types in form of an <a href="../../../../../mpl/index.html" target="_top">MPL</a>
- <a href="../../../../../mpl/doc/refmanual/forward-sequence.html" target="_top">Forward
Sequence</a> or another callable, builtin type
</p></dd>
<dt><span class="term"><code class="literal">Tag</code></span></dt>
<dd><p>
Further properties
</p></dd>
<dt><span class="term"><code class="literal">member_function_pointer&lt;Types,Tag&gt;::type</code></span></dt>
<dd><p>
Synthesized type
</p></dd>
</dl>
</div>
<p>
Synthesizes a member function pointer type from given properties.
</p>
<p>
An optional reference or possibly cv-qualified pointer is removed from
the second type in the sequence to determine the the class type. The cv-qualification
of the resulting type applies to the member function, unless otherwise
explicitly specified by the property tag.
</p>
<p>
If the template parameters do not describe a valid type, any attempt to
access the <code class="literal">type</code> member will result in a compile error.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="decomposition.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="tag_types.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,320 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Tag Types</title>
<link rel="stylesheet" href="../../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../reference.html" title=" Reference">
<link rel="prev" href="synthesis.html" title=" Class templates
for type synthesis">
<link rel="next" href="macros.html" title=" Macros">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="synthesis.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="macros.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_functiontypes.reference.tag_types"></a><a href="tag_types.html" title=" Tag Types"> Tag Types</a></h3></div></div></div>
<div class="toc"><dl>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.variadic">
variadic</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_variadic">
non_variadic</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.default_cc">
default_cc</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.const_qualified">
const_qualified</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_const">
non_const</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.volatile_qualified">
volatile_qualified</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_volatile">
non_volatile</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_cv"> non_cv</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.const_non_volatile">
const_non_volatile</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.volatile_non_const">
volatile_non_const</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.cv_qualfied">
cv_qualfied</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag">
null_tag</a></span></dt>
<dt><span class="section"><a href="tag_types.html#boost_functiontypes.reference.tag_types.tag"> tag</a></span></dt>
</dl></div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.variadic"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.variadic" title="
variadic">
variadic</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">variadic</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type takes a variable number of arguments through
an ellipsis parameter (such as <code class="literal">printf</code>).
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.non_variadic"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_variadic" title="
non_variadic">
non_variadic</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">non_variadic</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type does not have an ellipsis parameter.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.default_cc"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.default_cc" title="
default_cc">
default_cc</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">default_cc</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type encodes the default calling convention.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.const_qualified"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.const_qualified" title="
const_qualified">
const_qualified</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">const_qualified</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is const qualified.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.non_const"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_const" title="
non_const">
non_const</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">non_const</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is not const qualified.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.volatile_qualified"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.volatile_qualified" title="
volatile_qualified">
volatile_qualified</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">volatile_qualified</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is volatile qualified.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.non_volatile"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_volatile" title="
non_volatile">
non_volatile</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">non_volatile</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is not volatile qualified.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.non_cv"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.non_cv" title=" non_cv"> non_cv</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">non_cv</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is neither const nor volatile qualified. Equivalent
to <code class="computeroutput"><span class="identifier">__tag</span><span class="special">&lt;</span><span class="identifier">__non_const</span><span class="special">,</span><span class="identifier">__non_volatile</span><span class="special">&gt;</span></code>,
but involves fewer template instantiations when evaluated.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.const_non_volatile"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.const_non_volatile" title="
const_non_volatile">
const_non_volatile</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">const_non_volatile</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is const but not volatile qualified. Equivalent
to <code class="computeroutput"><span class="identifier">__tag</span><span class="special">&lt;</span><span class="identifier">__const_qualified</span><span class="special">,</span><span class="identifier">__non_volatile</span><span class="special">&gt;</span></code>,
but involves fewer template instantiations when evaluated.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.volatile_non_const"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.volatile_non_const" title="
volatile_non_const">
volatile_non_const</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">volatile_non_const</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is volatile but not const qualified. Equivalent
to <code class="computeroutput"><span class="identifier">__tag</span><span class="special">&lt;</span><span class="identifier">__volatile_qualified</span><span class="special">,</span><span class="identifier">__non_const</span><span class="special">&gt;</span></code>,
but involves fewer template instantiations when evaluated.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.cv_qualfied"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.cv_qualfied" title="
cv_qualfied">
cv_qualfied</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">cv_qualified</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States that a function type is both const and volatile qualified. Equivalent
to <code class="computeroutput"><span class="identifier">__tag</span><span class="special">&lt;</span><span class="identifier">__const_qualified</span><span class="special">,</span><span class="identifier">__volatile_qualified</span><span class="special">&gt;</span></code>,
but involves fewer template instantiations when evaluated.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.null_tag"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.null_tag" title="
null_tag">
null_tag</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">typedef</span> <span class="emphasis"><em>unspecified</em></span> <span class="identifier">null_tag</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<p>
States nothing.
</p>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_functiontypes.reference.tag_types.tag"></a><a href="tag_types.html#boost_functiontypes.reference.tag_types.tag" title=" tag"> tag</a></h4></div></div></div>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">Tag1</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Tag2</span><span class="special">,</span>
<span class="keyword">class</span> <span class="identifier">Tag3</span> <span class="special">=</span> <span class="identifier">null_tag</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Tag4</span> <span class="special">=</span> <span class="identifier">null_tag</span><span class="special">&gt;</span>
<span class="keyword">struct</span> <span class="identifier">tag</span><span class="special">;</span>
</pre>
<p>
<span class="bold"><strong>Header</strong></span>
</p>
<pre class="programlisting">
<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">function_types</span><span class="special">/</span><span class="identifier">property_tags</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<div class="variablelist">
<p class="title"><b></b></p>
<dl>
<dt><span class="term"><code class="literal">Tag<span class="emphasis"><em>N</em></span></code></span></dt>
<dd><p>
Property tag
</p></dd>
<dt><span class="term"><code class="literal">tag&lt;Tag1,Tag2...&gt;</code></span></dt>
<dd><p>
Compound property tag
</p></dd>
</dl>
</div>
<p>
Combination of up to four property tags. If the arguments describe different
values for the same property the value of the rightmost argument is used.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="synthesis.html"><img src="../../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../reference.html"><img src="../../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="macros.html"><img src="../../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,175 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title> Use Cases</title>
<link rel="stylesheet" href="../boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="up" href="../index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="prev" href="introduction.html" title=" Introduction">
<link rel="next" href="about_tag_types.html" title=" About Tag Types">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
<td align="center"><a href="../../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="introduction.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="about_tag_types.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
<div class="section" lang="en">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_functiontypes.use_cases"></a><a href="use_cases.html" title=" Use Cases"> Use Cases</a></h2></div></div></div>
<p>
Generic libraries that accept callable arguments are common in C++. Accepting
a callable argument of builin type often involves a lot of repetitive code
because the accepting function is overloaded for different function arities.
Further, member functions may have <code class="literal">const</code>/<code class="literal">volatile</code>-qualifiers,
a function may take a variable number of (additional, POD-typed) arguments
(such as <code class="literal">printf</code>) and several C++ implementations encode
a calling convention with each function's type to allow calls across language
or (sub-)system boundaries.
</p>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(*</span> <span class="identifier">func</span><span class="special">)());</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(&amp;</span> <span class="identifier">func</span><span class="special">)());</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)());</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)()</span> <span class="keyword">const</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)()</span> <span class="keyword">volatile</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)()</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(*</span> <span class="identifier">func</span><span class="special">)(...));</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(&amp;</span> <span class="identifier">func</span><span class="special">)(...));</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...));</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...)</span> <span class="keyword">const</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...)</span> <span class="keyword">volatile</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">C</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">R</span><span class="special">(</span><span class="identifier">C</span><span class="special">::*</span> <span class="identifier">func</span><span class="special">)(...)</span> <span class="keyword">const</span> <span class="keyword">volatile</span><span class="special">);</span>
<span class="comment">// ...
</span>
<span class="comment">// needs to be repeated for every additional function parameter
</span><span class="comment">// times the number of possible calling conventions
</span></pre>
<p>
The "overloading approach" obviously does not scale well: There might
be several functions that accept callable arguments in one library and client
code might end up using several libraries that use this pattern. On the developer
side, library developers spend their time solving the same problem, working
around the same portability issues, and apply similar optimizations to keep
the compilation time down.
</p>
<p>
Using Boost.FunctionTypes it is possible to write a single function template
instead:
</p>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">F</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">accept_function</span><span class="special">(</span><span class="identifier">F</span> <span class="identifier">f</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">// ... use Boost.FunctionTypes to analyse F
</span><span class="special">}</span>
</pre>
<p>
The combination with a tuples library that provides an invoker component, such
as <a href="../../../../fusion/index.html" target="_top">Boost.Fusion</a>, allows to
build flexible callback facilities that are entirely free of repetitive code
as shown by the <a href="../../../../function_types/example/interpreter.hpp" target="_top">interpreter
example</a>.
</p>
<p>
When taking the address of an overloaded function or function template, the
type of the function must be known from the context the expression is used
in. The code below shows three examples for choosing the <code class="literal">float(float)</code>
overload of <code class="literal">std::abs</code>.
</p>
<pre class="programlisting">
<span class="keyword">float</span> <span class="special">(*</span><span class="identifier">ptr_absf</span><span class="special">)(</span><span class="keyword">float</span><span class="special">)</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">;</span>
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">(</span><span class="keyword">float</span><span class="special">(*</span><span class="identifier">func</span><span class="special">)(</span><span class="keyword">float</span><span class="special">));</span>
<span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">foo</span><span class="special">(&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">);</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">transform</span><span class="special">(</span><span class="identifier">b</span><span class="special">,</span> <span class="identifier">e</span><span class="special">,</span> <span class="identifier">o</span><span class="special">,</span> <span class="keyword">static_cast</span><span class="special">&lt;</span><span class="keyword">float</span><span class="special">(*)(</span><span class="keyword">float</span><span class="special">)&gt;(&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">abs</span><span class="special">));</span>
</pre>
<p>
The library's type synthesis capabilities can be used to automate overload
selection and instantiation of function templates. Given an overloaded function
template
</p>
<pre class="programlisting">
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">&gt;</span>
<span class="identifier">R</span> <span class="identifier">overloaded</span><span class="special">(</span><span class="identifier">T0</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">&gt;</span>
<span class="identifier">R</span> <span class="identifier">overloaded</span><span class="special">(</span><span class="identifier">T0</span><span class="special">,</span><span class="identifier">T1</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">R</span><span class="special">.</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span><span class="special">&gt;</span>
<span class="identifier">R</span> <span class="identifier">overloaded</span><span class="special">(</span><span class="identifier">T0</span><span class="special">,</span><span class="identifier">T1</span><span class="special">,</span><span class="identifier">T2</span><span class="special">);</span>
</pre>
<p>
we can pick any of the three overloads and instantiate the template with template
arguments from a type sequence in a single expression:
</p>
<pre class="programlisting">
<span class="keyword">static_cast</span><span class="special">&lt;</span><a href="reference/synthesis.html#boost_functiontypes.reference.synthesis.function_pointer" title="
function_pointer">function_pointer</a><span class="special">&lt;</span><span class="identifier">Seq</span><span class="special">&gt;::</span><span class="identifier">type</span><span class="special">&gt;(&amp;</span> <span class="identifier">overloaded</span><span class="special">)</span>
</pre>
<p>
This technique can be occasionally more flexible than template argument deduction
from a function call because the exact types from the sequence are used to
specialize the template (including possibly cv-qualified reference types and
the result type). It is applied twice in the <a href="../../../../function_types/example/interface.hpp" target="_top">interface
example</a>.
</p>
<p>
Another interersting property of callable, builtin types is that they can be
valid types for non-type template parameters. This way, a function can be pinpointed
at compile time, allowing the compiler to eliminate the call by inlining. The
<a href="../../../../function_types/example/fast_mem_fn.hpp" target="_top">fast_mem_fn example</a>
exploits this characteristic and implements a potentially inlining version
of <a href="../../../../bind/mem_fn.html" target="_top">boost::mem_fn</a> limited to
member functions that are known at compile time.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><small>Copyright <20> 2004 -2007 Tobias Schwinger</small></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="introduction.html"><img src="../../../../../doc/html/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/html/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/html/images/home.png" alt="Home"></a><a accesskey="n" href="about_tag_types.html"><img src="../../../../../doc/html/images/next.png" alt="Next"></a>
</div>
</body>
</html>

528
doc/html/boostbook.css Normal file
View File

@ -0,0 +1,528 @@
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
http://spirit.sourceforge.net/
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
/*=============================================================================
Body defaults
=============================================================================*/
body
{
margin: 1em;
font-family: sans-serif;
}
/*=============================================================================
Paragraphs
=============================================================================*/
p
{
text-align: left;
font-size: 10pt;
line-height: 1.15;
}
/*=============================================================================
Program listings
=============================================================================*/
/* Code on paragraphs */
p tt.computeroutput
{
font-size: 9pt;
}
pre.synopsis
{
font-size: 90%;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.programlisting,
.screen
{
font-size: 9pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
/* Program listings in tables don't get borders */
td .programlisting,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}
/*=============================================================================
Headings
=============================================================================*/
h1, h2, h3, h4, h5, h6
{
text-align: left;
margin: 1em 0em 0.5em 0em;
font-weight: bold;
}
h1 { font: 140% }
h2 { font: bold 140% }
h3 { font: bold 130% }
h4 { font: bold 120% }
h5 { font: italic 110% }
h6 { font: italic 100% }
/* Top page titles */
title,
h1.title,
h2.title
h3.title,
h4.title,
h5.title,
h6.title,
.refentrytitle
{
font-weight: bold;
margin-bottom: 1pc;
}
h1.title { font-size: 140% }
h2.title { font-size: 140% }
h3.title { font-size: 130% }
h4.title { font-size: 120% }
h5.title { font-size: 110% }
h6.title { font-size: 100% }
.section h1
{
margin: 0em 0em 0.5em 0em;
font-size: 140%;
}
.section h2 { font-size: 140% }
.section h3 { font-size: 130% }
.section h4 { font-size: 120% }
.section h5 { font-size: 110% }
.section h6 { font-size: 100% }
/* Code on titles */
h1 tt.computeroutput { font-size: 140% }
h2 tt.computeroutput { font-size: 140% }
h3 tt.computeroutput { font-size: 130% }
h4 tt.computeroutput { font-size: 120% }
h5 tt.computeroutput { font-size: 110% }
h6 tt.computeroutput { font-size: 100% }
/*=============================================================================
Author
=============================================================================*/
h3.author
{
font-size: 100%
}
/*=============================================================================
Lists
=============================================================================*/
li
{
font-size: 10pt;
line-height: 1.3;
}
/* Unordered lists */
ul
{
text-align: left;
}
/* Ordered lists */
ol
{
text-align: left;
}
/*=============================================================================
Links
=============================================================================*/
a
{
text-decoration: none; /* no underline */
}
a:hover
{
text-decoration: underline;
}
/*=============================================================================
Spirit style navigation
=============================================================================*/
.spirit-nav
{
text-align: right;
}
.spirit-nav a
{
color: white;
padding-left: 0.5em;
}
.spirit-nav img
{
border-width: 0px;
}
/*=============================================================================
Table of contents
=============================================================================*/
.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 80%;
line-height: 1.15;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/*=============================================================================
Tables
=============================================================================*/
.table-title,
div.table p.title
{
margin-left: 4%;
padding-right: 0.5em;
padding-left: 0.5em;
}
.informaltable table,
.table table
{
width: 92%;
margin-left: 4%;
margin-right: 4%;
}
div.informaltable table,
div.table table
{
padding: 4px;
}
/* Table Cells */
div.informaltable table tr td,
div.table table tr td
{
padding: 0.5em;
text-align: left;
font-size: 9pt;
}
div.informaltable table tr th,
div.table table tr th
{
padding: 0.5em 0.5em 0.5em 0.5em;
border: 1pt solid white;
font-size: 80%;
}
/*=============================================================================
Blurbs
=============================================================================*/
div.note,
div.tip,
div.important,
div.caution,
div.warning,
div.sidebar
{
font-size: 9pt; /* A little bit smaller than the main text */
line-height: 1.2;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.0pc 0.5pc;
}
div.sidebar img
{
padding: 1pt;
}
/*=============================================================================
Callouts
=============================================================================*/
.line_callout_bug img
{
float: left;
position:relative;
left: 4px;
top: -12px;
clear: left;
margin-left:-22px;
}
.callout_bug img
{
}
/*=============================================================================
Variable Lists
=============================================================================*/
/* Make the terms in definition lists bold */
div.variablelist dl dt,
span.term
{
font-weight: bold;
font-size: 10pt;
}
div.variablelist table tbody tr td
{
text-align: left;
vertical-align: top;
padding: 0em 2em 0em 0em;
font-size: 10pt;
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
div.variablelist dl dt
{
margin-bottom: 0.2em;
}
div.variablelist dl dd
{
margin: 0em 0em 0.5em 2em;
font-size: 10pt;
}
div.variablelist table tbody tr td p,
div.variablelist dl dd p
{
margin: 0em 0em 0.5em 0em;
line-height: 1;
}
/*=============================================================================
Misc
=============================================================================*/
/* Title of books and articles in bibliographies */
span.title
{
font-style: italic;
}
span.underline
{
text-decoration: underline;
}
span.strikethrough
{
text-decoration: line-through;
}
/* Copyright, Legal Notice */
div div.legalnotice p
{
text-align: left
}
/*=============================================================================
Colors
=============================================================================*/
@media screen
{
/* Links */
a
{
color: #005a9c;
}
a:visited
{
color: #9c5a9c;
}
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
{
text-decoration: none; /* no underline */
color: #000000;
}
/* Syntax Highlighting */
.keyword { color: #0000AA; }
.identifier { color: #000000; }
.special { color: #707070; }
.preprocessor { color: #402080; }
.char { color: teal; }
.comment { color: #800000; }
.string { color: teal; }
.number { color: teal; }
.white_bkd { background-color: #FFFFFF; }
.dk_grey_bkd { background-color: #999999; }
/* Copyright, Legal Notice */
.copyright
{
color: #666666;
font-size: small;
}
div div.legalnotice p
{
color: #666666;
}
/* Program listing */
pre.synopsis
{
border: 1px solid #DCDCDC;
}
.programlisting,
.screen
{
border: 1px solid #DCDCDC;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Blurbs */
div.note,
div.tip,
div.important,
div.caution,
div.warning,
div.sidebar
{
border: 1px solid #DCDCDC;
}
/* Table of contents */
.toc
{
border: 1px solid #DCDCDC;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid #DCDCDC;
}
div.informaltable table tr th,
div.table table tr th
{
background-color: #F0F0F0;
border: 1px solid #DCDCDC;
}
/* Misc */
span.highlight
{
color: #00A000;
}
}
@media print
{
/* Links */
a
{
color: black;
}
a:visited
{
color: black;
}
.spirit-nav
{
display: none;
}
/* Program listing */
pre.synopsis
{
border: 1px solid gray;
}
.programlisting,
.screen
{
border: 1px solid gray;
}
td .programlisting,
td .screen
{
border: 0px solid #DCDCDC;
}
/* Table of contents */
.toc
{
border: 1px solid gray;
}
.informaltable table,
.table table
{
border: 1px solid gray;
border-collapse: collapse;
}
/* Tables */
div.informaltable table tr td,
div.table table tr td
{
border: 1px solid gray;
}
div.informaltable table tr th,
div.table table tr th
{
border: 1px solid gray;
}
/* Misc */
span.highlight
{
font-weight: bold;
}
}

55
doc/html/index.html Normal file
View File

@ -0,0 +1,55 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Chapter<EFBFBD>1.<2E>Boost.FunctionTypes 2.5</title>
<link rel="stylesheet" href="boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
<link rel="start" href="index.html" title="Chapter<65>1.<2E>Boost.FunctionTypes 2.5">
<link rel="next" href="boost_functiontypes/introduction.html" title=" Introduction">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../boost.png"></td>
<td align="center"><a href="../../../../index.htm">Home</a></td>
<td align="center"><a href="../../../libraries.htm">Libraries</a></td>
<td align="center"><a href="../../../../people/people.htm">People</a></td>
<td align="center"><a href="../../../../more/faq.htm">FAQ</a></td>
<td align="center"><a href="../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="boost_functiontypes/introduction.html"><img src="../../../../doc/html/images/next.png" alt="Next"></a></div>
<div class="chapter" lang="en">
<div class="titlepage"><div>
<div><h2 class="title">
<a name="boost_functiontypes"></a>Chapter<EFBFBD>1.<2E>Boost.FunctionTypes 2.5</h2></div>
<div><div class="author"><h3 class="author">
<span class="firstname">Tobias</span> <span class="surname">Schwinger</span>
</h3></div></div>
<div><p class="copyright">Copyright <20> 2004 -2007 Tobias Schwinger</p></div>
<div><div class="legalnotice">
<a name="id905079"></a><p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
</p>
</div></div>
</div></div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="section"><a href="boost_functiontypes/introduction.html"> Introduction</a></span></dt>
<dt><span class="section"><a href="boost_functiontypes/use_cases.html"> Use Cases</a></span></dt>
<dt><span class="section"><a href="boost_functiontypes/about_tag_types.html"> About Tag Types</a></span></dt>
<dt><span class="section"><a href="boost_functiontypes/reference.html"> Reference</a></span></dt>
<dt><span class="section"><a href="boost_functiontypes/rationale.html"> Rationale</a></span></dt>
<dt><span class="section"><a href="boost_functiontypes/acknowledgements.html"> Acknowledgements</a></span></dt>
</dl>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: May 13, 2007 at 13:12:48 GMT</small></p></td>
<td align="right"><small></small></td>
</tr></table>
<hr>
<div class="spirit-nav"><a accesskey="n" href="boost_functiontypes/introduction.html"><img src="../../../../doc/html/images/next.png" alt="Next"></a></div>
</body>
</html>

20
example/Jamfile Normal file
View File

@ -0,0 +1,20 @@
# (C) Copyright Tobias Schwinger
#
# Use, modification and distribution are subject to the Boost Software License,
# Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
#-------------------------------------------------------------------------------
exe interpreter_example : interpreter_example.cpp ;
exe result_of_example : result_of_example.cpp ;
exe interface_example : interface_example.cpp ;
exe fast_mem_fn_example : fast_mem_fn_example.cpp
: <include>. ; # needed for Boost.PP file iteration with some compilers
exe macro_type_args_example : macro_type_args_example.cpp ;

View File

@ -0,0 +1,71 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
// Metafunction to compute optimal parameter type for argument forwarding.
// This header is not an FT example in itself -- it's used by some of them to
// optimize argument forwarding.
//
// For more details see 'fast_mem_fn.hpp' in this directory or the documentation
// of the CallTraits utility [1].
//
//
// References
// ==========
//
// [1] http://www.boost.org/libs/utility/call_traits.htm
#ifndef BOOST_UTILITY_PARAM_TYPE_HPP_INCLUDED
#define BOOST_UTILITY_PARAM_TYPE_HPP_INCLUDED
#include <boost/config.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/type_traits/add_reference.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/aux_/lambda_support.hpp>
// #include <boost/type_traits/detail/template_arity_spec.hpp>
// namespace boost
namespace example
{
namespace mpl = boost::mpl;
// namespace utility
// {
namespace param_type_detail
{
template<typename T>
struct by_ref_cond
{
typedef by_ref_cond type;
BOOST_STATIC_CONSTANT(bool,value = sizeof(void*) < sizeof(T));
};
template<typename T>
struct add_ref_to_const
: boost::add_reference< typename boost::add_const<T>::type >
{ };
}
template<typename T>
struct param_type
: mpl::eval_if< param_type_detail::by_ref_cond<T>
, param_type_detail::add_ref_to_const<T>, mpl::identity<T> >
{
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,param_type,(T))
};
// }
// BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,utility::param_type)
}
#endif

248
example/fast_mem_fn.hpp Normal file
View File

@ -0,0 +1,248 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
//
// This example implements a very efficient, generic member function wrapper.
//
//
// Detailed description
// ====================
//
// For most platforms C++ runs on (maybe all hardware platforms, as opposed to
// virtual machines) there are indirect calls that take more time to execute
// than direct ones. Further calling a function usually takes more time than
// inlining it at the call site.
//
// A direct call is a machine instruction that calls a subroutine at a known
// address encoded in the instruction itself. C++ compilers usually emit one of
// these instructions for each function call to a nonvirtual function (a call to
// a virtual function requires either two direct calls or one indirect call).
// An indirect call is a machine instruction that calls a subroutine at an
// address known at runtime. C++ compilers usually emit at least one of these
// instructions for a call through a callable builtin variable.
//
// It is possible to use callable scalars as non-type template arguments. This
// way the compiler knows which function we want to call when generating the
// code for the call site, so it may inline (if it decides to do so) or use a
// direct call instead of being forced to use a slow, indirect call.
//
// We define a functor class template that encodes the function to call in its
// type via a non-type template argument. Its (inline declared) overloaded
// function call operator calls the function through that non-type template
// argument. In the best case we end up inlining the callee directly at the
// point of the call.
//
// Decomposition of the wrapped member function's type is needed in order to
// implement argument forwarding (just using a templated call operator we would
// encounter what is known as "the forwarding problem" [Dimov1]). Further we
// can eliminate unecessary copies for each by-value parameter by using a
// reference to its const qualified type for the corresponding parameter of the
// wrapper's function call operator.
//
// Finally we provide a macro that does have similar semantics to the function
// template mem_fn of the Bind [2] library.
// We can't use a function template and use a macro instead, because we use a
// member function pointer that is a compile time constant. So we first have to
// deduce the type and create a template that accepts this type as a non-type
// template argument, which is passed in in a second step. The macro hides this
// lengthy expression from the user.
//
//
// Limitations
// ===========
//
// The "this-argument" must be specified as a reference.
//
//
// Bibliography
// ============
//
// [Dimov1] Dimov, P., Hinnant H., Abrahams, D. The Forwarding Problem
// http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
//
// [Dimov2] Dimov, P. Documentation of boost::mem_fn
// http://www.boost.org/libs/bind/mem_fn.html
#ifndef BOOST_EXAMPLE_FAST_MEM_FN_HPP_INCLUDED
#ifndef BOOST_PP_IS_ITERATING
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/parameter_types.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
#include <boost/mpl/transform_view.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/utility/enable_if.hpp>
#include "detail/param_type.hpp"
namespace example
{
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
// the functor class template
template< typename MFPT, MFPT MemberFunction
, size_t Arity = ::example::ft::function_arity<MFPT>::value
>
struct fast_mem_fn;
// ------- ---- --- -- - - - -
// deduce type and capture compile time value
#define BOOST_EXAMPLE_FAST_MEM_FN(mfp) \
::example::make_fast_mem_fn(mfp).make_fast_mem_fn<mfp>()
template<typename MFPT>
struct fast_mem_fn_maker
{
template<MFPT Callee>
fast_mem_fn<MFPT,Callee> make_fast_mem_fn()
{
return fast_mem_fn<MFPT,Callee>();
}
};
template<typename MFPT>
typename boost::enable_if<boost::is_member_function_pointer<MFPT>,
fast_mem_fn_maker<MFPT> >::type
make_fast_mem_fn(MFPT)
{
return fast_mem_fn_maker<MFPT>();
}
// ------- ---- --- -- - - - -
namespace detail
{
// by-value forwarding optimization
template<typename T>
struct parameter_types
: mpl::transform_view<ft::parameter_types<T>,param_type<_> >
{ };
}
// ------- ---- --- -- - - - -
template< typename MFPT, MFPT MemberFunction >
struct fast_mem_fn<MFPT, MemberFunction, 1>
{
// decompose the result and the parameter types (public for introspection)
typedef typename ft::result_type<MFPT>::type result_type;
typedef detail::parameter_types<MFPT> parameter_types;
private:
// iterate the parameter types
typedef typename mpl::begin<parameter_types>::type i0;
public:
// forwarding function call operator
result_type operator()( typename mpl::deref<i0>::type a0) const
{
return (a0.*MemberFunction)();
};
};
template< typename MFPT, MFPT MemberFunction >
struct fast_mem_fn<MFPT, MemberFunction, 2>
{
// decompose the result and the parameter types (public for introspection)
typedef typename ft::result_type<MFPT>::type result_type;
typedef detail::parameter_types<MFPT> parameter_types;
private:
// iterate the parameter types
typedef typename mpl::begin<parameter_types>::type i0;
typedef typename mpl::next<i0>::type i1;
public:
// forwarding function call operator
result_type operator()( typename mpl::deref<i0>::type a0
, typename mpl::deref<i1>::type a1) const
{
return (a0.*MemberFunction)(a1);
};
};
template< typename MFPT, MFPT MemberFunction >
struct fast_mem_fn<MFPT, MemberFunction, 3>
{
// decompose the result and the parameter types (public for introspection)
typedef typename ft::result_type<MFPT>::type result_type;
typedef detail::parameter_types<MFPT> parameter_types;
private:
// iterate the parameter types
typedef typename mpl::begin<parameter_types>::type i0;
typedef typename mpl::next<i0>::type i1;
typedef typename mpl::next<i1>::type i2;
public:
// forwarding function call operator
result_type operator()( typename mpl::deref<i0>::type a0
, typename mpl::deref<i1>::type a1
, typename mpl::deref<i2>::type a2) const
{
return (a0.*MemberFunction)(a1,a2);
};
};
// ...
}
// ------- ---- --- -- - - - -
// preprocessor-based code generator to continue the repetitive part, above
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
namespace example
{
#if BOOST_FT_MAX_ARITY >= 4
# define BOOST_PP_FILENAME_1 "fast_mem_fn.hpp"
# define BOOST_PP_ITERATION_LIMITS (4,BOOST_FT_MAX_ARITY)
# include BOOST_PP_ITERATE()
#endif
}
#define BOOST_EXAMPLE_FAST_MEM_FN_HPP_INCLUDED
#else
#define N BOOST_PP_FRAME_ITERATION(1)
template< typename MFPT, MFPT MemberFunction >
struct fast_mem_fn<MFPT, MemberFunction, N >
{
// decompose the result and the parameter types (public for introspection)
typedef typename ft::result_type<MFPT>::type result_type;
typedef detail::parameter_types<MFPT> parameter_types;
private:
// iterate the parameter types
typedef typename mpl::begin<parameter_types>::type i0;
#define BOOST_PP_LOCAL_LIMITS (0,N-2)
#define BOOST_PP_LOCAL_MACRO(j) \
typedef typename mpl::next< i ## j >::type BOOST_PP_CAT(i,BOOST_PP_INC(j)) ;
#include BOOST_PP_LOCAL_ITERATE()
public:
// forwarding function call operator
result_type operator()(
BOOST_PP_ENUM_BINARY_PARAMS(N, typename mpl::deref<i,>::type a) ) const
{
return (a0.*MemberFunction)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,a));
};
};
#undef N
#endif
#endif

View File

@ -0,0 +1,118 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
// See fast_mem_fn.hpp in this directory for details.
#include <vector>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <functional>
#include <boost/timer.hpp>
#include <boost/mem_fn.hpp>
#include "fast_mem_fn.hpp"
// test class that holds a single integer with getter function
class test
{
int val_id;
public:
explicit test(int id)
: val_id(id)
{ }
int id() const
{ return val_id; }
};
// STL style comparator that applies the CriterionExtractor function to both
// operands and compares the results with Comparator
template<typename CriterionExtractor, typename Comparator>
class test_compare
{
CriterionExtractor fnc_criterion;
Comparator fnc_compare;
public:
explicit test_compare(CriterionExtractor criterion, Comparator compare)
: fnc_criterion(criterion)
, fnc_compare(compare)
{ }
template<typename T>
inline bool operator()(T const & lhs, T const & rhs) const
{
return fnc_compare(fnc_criterion(lhs),fnc_criterion(rhs));
}
};
// helper function to construct an instance of the test_compare comparator.
template<typename CriterionExtractor, typename Comparator>
test_compare<CriterionExtractor,Comparator>
make_test_compare(CriterionExtractor criterion, Comparator compare)
{
return test_compare<CriterionExtractor,Comparator>(criterion,compare);
}
// the test case: sort N test objects by id
//
// the objects are in ascending order before the test run and in descending
// order after it
static const unsigned N = 2000000;
typedef std::vector<test> test_vector;
void setup_test(test_vector & v)
{
v.clear();
v.reserve(N);
for (unsigned i = 0; i < N; ++i)
v.push_back(test(i));
}
template<typename F> void do_test(test_vector & v, F criterion)
{
std::sort(v.begin(),v.end(),make_test_compare(criterion,std::greater<int>()));
assert(v.begin()->id() == N-1);
}
// compare performance with boost::mem_fn
int main()
{
test_vector v;
boost::timer t;
double time1, time2;
std::cout <<
"Test case: sorting " << N << " objects.\n\n"
"Criterion accessor called with | elasped seconds\n"
"-------------------------------|----------------" << std::endl;
setup_test(v);
t.restart();
do_test(v, BOOST_EXAMPLE_FAST_MEM_FN(& test::id));
time1 = t.elapsed();
std::cout << "fast_mem_fn | " << time1 << std::endl;
setup_test(v);
t.restart();
do_test(v, boost::mem_fn(& test::id));
time2 = t.elapsed();
std::cout << "mem_fn | " << time2 << std::endl;
std::cout << '\n' << (time2/time1-1)*100 << "% speedup" << std::endl;
return 0;
}

361
example/interface.hpp Normal file
View File

@ -0,0 +1,361 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
//
// This example implements interfaces.
//
// Detailed description
// ====================
//
// An interface is a collection of member function prototypes that may be
// implemented by classes. Objects of classes that implement the interface can
// then be assigned to an interface variable through which the interface's
// functions can be called.
//
// Interfaces are a feature of the Java programming language [Gosling] and the
// most obvious way to model interfaces in C++ is (multiple) inheritance.
// Using inheritance for this purpose, however, is neither the most efficient
// nor the most flexible solution, because:
//
// - all functions must be virtual,
//
// => a function that calls another function of the interface must do so
// via virtual dispatch (as opposed to inlining)
// => a class can not implement an interface's (overloaded) function via
// a function template
//
// - inhertitance is intrusive
//
// => object size increases
// => client's are always polymorphic
// => dependencies cause tighter coupling
//
// Fortunately it is possible to eliminate all the drawbacks mentioned above
// based on an alternative implementation proposed by David Abrahams.
// We'll add some detail to the original scheme (see [Abrahams]) such as
// support for overloaded and const qualified functions.
// The implementation in this example uses Boost.FunctionTypes to shift
// metaprogramming code from the preprocessor into templates, to reduce
// preprocessing time and increase maintainability.
//
//
// Limitations
// ===========
//
// There is no lifetime management as implemented by the Boost candidate
// Interfaces library (see [Turkanis]).
//
// This example does not compile with Visual C++. Template argument deduction
// from the result of the address-of operator does not work properly with this
// compiler. It is possible to partially work around the problem, but it isn't
// done here for the sake of readability.
//
//
// Bibliography
// ============
//
// [Gosling] Gosling, J., Joy, B., Steele, G. The Java Language Specification
// http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html
//
// [Abrahams] Abrahams, D. Proposal: interfaces, Post to newsgroup comp.std.c++
// http://groups.google.com/group/comp.std.c++/msg/85af30a61bf677e4
//
// [Turkanis] Turkanis, J., Diggins, C. Boost candidate Interfaces library
// http://www.kangaroologic.com/interfaces/libs/interfaces/doc/index.html
#include <cstddef>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/member_function_pointer.hpp>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/utility/addressof.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/single_view.hpp>
#include <boost/mpl/transform_view.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/seq/elem.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/arithmetic/dec.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/preprocessor/facilities/identity.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include "detail/param_type.hpp"
namespace example
{
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
// join a single type and an MPL-sequence
// in some ways similar to mpl::push_front (but mpl::push_front requires
// an MPL Extensible Sequence and this template does not)
template<typename T, typename Seq>
struct concat_view
: mpl::joint_view<mpl::single_view<T>, Seq>
{ };
// metafunction returning a function pointer type for a vtable entry
template<typename Inf>
struct vtable_entry
: ft::function_pointer
< concat_view< typename Inf::result, mpl::transform_view<
typename Inf::params, param_type<_> > > >
{ };
// the expression '& member<MetaInfo,Tag>::wrap<& Class::Function> ' in an
// assignment context binds the member function Function of Class with the
// properties described by MetaInfo and Tag to the corresponding vtable
// entry
template<typename Inf, typename Tag>
struct member
{
typedef typename ft::member_function_pointer
< concat_view<typename Inf::result,typename Inf::params>,Tag
>::type
mem_func_ptr;
typedef typename mpl::at_c<typename Inf::params,0>::type context;
template<mem_func_ptr MemFuncPtr>
static typename Inf::result wrap(void* c)
{
return (reinterpret_cast<context*>(c)->*MemFuncPtr)();
}
template<mem_func_ptr MemFuncPtr, typename T0>
static typename Inf::result wrap(void* c, T0 a0)
{
return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0);
}
template<mem_func_ptr MemFuncPtr, typename T0, typename T1>
static typename Inf::result wrap(void* c, T0 a0, T1 a1)
{
return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0,a1);
}
// continue with the preprocessor (the scheme should be clear, by now)
#define BOOST_PP_LOCAL_MACRO(n) \
template<mem_func_ptr MemFuncPtr, BOOST_PP_ENUM_PARAMS(n,typename T)> \
static typename Inf::result wrap(void* c, \
BOOST_PP_ENUM_BINARY_PARAMS(n,T,a)) \
{ \
return (reinterpret_cast<context*>(c)->*MemFuncPtr)( \
BOOST_PP_ENUM_PARAMS(n,a) ); \
}
#define BOOST_PP_LOCAL_LIMITS (3,BOOST_FT_MAX_ARITY-1)
#include BOOST_PP_LOCAL_ITERATE()
};
// extract a parameter by index
template<typename Inf, std::size_t Index>
struct param
: param_type< typename mpl::at_c< typename Inf::params,Index>::type >
{ };
}
// the interface definition on the client's side
#define BOOST_EXAMPLE_INTERFACE(name,def) \
class name \
{ \
struct vtable \
{ \
BOOST_EXAMPLE_INTERFACE__MEMBERS(def,VTABLE) \
}; \
\
vtable const * ptr_vtable; \
void * ptr_that; \
\
template<class T> struct vtable_holder \
{ \
static vtable const val_vtable; \
}; \
\
public: \
\
template<class T> \
inline name (T & that) \
: ptr_vtable(& vtable_holder<T>::val_vtable) \
, ptr_that(boost::addressof(that)) \
{ } \
\
BOOST_EXAMPLE_INTERFACE__MEMBERS(def,FUNCTION) \
}; \
\
template<typename T> \
name ::vtable const name ::vtable_holder<T>::val_vtable \
= { BOOST_EXAMPLE_INTERFACE__MEMBERS(def,INIT_VTABLE) }
#ifdef BOOST_PP_NIL // never defined -- a comment with syntax highlighting
BOOST_EXAMPLE_INTERFACE( interface_x,
(( a_func, (void)(int), const_qualified ))
(( another_func, (int), non_const ))
);
// expands to:
class interface_x
{
struct vtable
{
// meta information for first function
template<typename T = void*> struct inf0
{
typedef void result;
typedef ::boost::mpl::vector< T, int > params;
};
// function pointer with void* context pointer and parameters optimized
// for forwarding
::example::vtable_entry<inf0<> >::type func0;
// second function
template<typename T = void*> struct inf1
{
typedef int result;
typedef ::boost::mpl::vector< T > params;
};
::example::vtable_entry<inf1<> >::type func1;
};
// data members
vtable const * ptr_vtable;
void * ptr_that;
// this template is instantiated for every class T this interface is created
// from, causing the compiler to emit an initialized vtable for this type
// (see aggregate assignment, below)
template<class T> struct vtable_holder
{
static vtable const val_vtable;
};
public:
// converting ctor, creates an interface from an arbitrary class
template<class T>
inline interface_x (T & that)
: ptr_vtable(& vtable_holder<T>::val_vtable)
, ptr_that(boost::addressof(that))
{ }
// the member functions from the interface definition, parameters are
// optimized for forwarding
inline vtable::inf0<> ::result a_func (
::example::param<vtable::inf0<>,1>::type p0) const
{
return ptr_vtable-> func0(ptr_that , p0);
}
inline vtable::inf1<> ::result another_func ()
{
return ptr_vtable-> func1(ptr_that );
}
};
template<typename T>
interface_x ::vtable const interface_x ::vtable_holder<T>::val_vtable =
{
// instantiate function templates that wrap member function pointers (which
// are known at compile time) by taking their addresses in assignment to
// function pointer context
& ::example::member< vtable::inf0<T>, ::example::ft:: const_qualified >
::template wrap < &T:: a_func >
, & ::example::member< vtable::inf1<T>, ::example::ft:: non_const >
::template wrap < &T:: another_func >
};
#endif
// preprocessing code details
// iterate all of the interface's members and invoke a macro (prefixed with
// BOOST_EXAMPLE_INTERFACE_)
#define BOOST_EXAMPLE_INTERFACE__MEMBERS(seq,macro) \
BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), \
BOOST_EXAMPLE_INTERFACE__ ## macro,seq)
// extract signature sequence from entry
#define BOOST_EXAMPLE_INTERFACE__VTABLE(z,i,seq) \
BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i, \
BOOST_PP_TUPLE_ELEM(3,1,BOOST_PP_SEQ_ELEM(i,seq)))
// split the signature sequence result/params and insert T at the beginning of
// the params part
#define BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i,seq) \
BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i, \
BOOST_PP_SEQ_HEAD(seq),(T)BOOST_PP_SEQ_TAIL(seq))
// emit the meta information structure and function pointer declaration
#define BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i,result_type,param_types) \
template<typename T = void*> \
struct BOOST_PP_CAT(inf,i) \
{ \
typedef result_type result; \
typedef ::boost::mpl::vector< BOOST_PP_SEQ_ENUM(param_types) > params; \
}; \
::example::vtable_entry<BOOST_PP_CAT(inf,i)<> >::type BOOST_PP_CAT(func,i);
// extract tuple entry from sequence and precalculate the name of the function
// pointer variable
#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE(z,i,seq) \
BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,BOOST_PP_CAT(func,i), \
BOOST_PP_SEQ_ELEM(i,seq))
// emit a function pointer expression that encapsulates the corresponding
// member function of T
#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,func,desc) \
BOOST_PP_COMMA_IF(i) & ::example::member< BOOST_PP_CAT(vtable::inf,i)<T>, \
::example::ft:: BOOST_PP_TUPLE_ELEM(3,2,desc) >::template wrap \
< &T:: BOOST_PP_TUPLE_ELEM(3,0,desc) >
// extract tuple entry from sequence
#define BOOST_EXAMPLE_INTERFACE__FUNCTION(z,i,seq) \
BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,BOOST_PP_SEQ_ELEM(i,seq))
// precalculate function name, arity, name of meta info structure and cv-
// qualifiers
#define BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,desc) \
BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i, \
BOOST_PP_TUPLE_ELEM(3,0,desc), \
BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(3,1,desc))), \
BOOST_PP_CAT(vtable::inf,i)<>, \
BOOST_PP_CAT(BOOST_EXAMPLE_INTERFACE___,BOOST_PP_TUPLE_ELEM(3,2,desc)) \
)
// emit the definition for a member function of the interface
#define BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i,name,arity,types,cv) \
inline types ::result name \
(BOOST_PP_ENUM_ ## z (arity,BOOST_EXAMPLE_INTERFACE__PARAM,types)) cv() \
{ \
return ptr_vtable-> BOOST_PP_CAT(func,i)(ptr_that \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,arity,p)); \
}
// emit a parameter of the function definition
#define BOOST_EXAMPLE_INTERFACE__PARAM(z,j,types) \
::example::param<types,BOOST_PP_INC(j)>::type BOOST_PP_CAT(p,j)
// helper macros to map 'const_qualified' to 'const' an 'non_const' to ''
#define BOOST_EXAMPLE_INTERFACE___const_qualified BOOST_PP_IDENTITY(const)
#define BOOST_EXAMPLE_INTERFACE___non_const BOOST_PP_EMPTY

View File

@ -0,0 +1,79 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
// See interface.hpp in this directory for details.
#include <iostream>
#include "interface.hpp"
BOOST_EXAMPLE_INTERFACE( interface_x,
(( a_func, (void)(int) , const_qualified ))
(( a_func, (void)(long), const_qualified ))
(( another_func, (int) , non_const ))
);
// two classes that implement interface_x
struct a_class
{
void a_func(int v) const
{
std::cout << "a_class::void a_func(int v = " << v << ")" << std::endl;
}
void a_func(long v) const
{
std::cout << "a_class::void a_func(long v = " << v << ")" << std::endl;
}
int another_func()
{
std::cout << "a_class::another_func() = 3" << std::endl;
return 3;
}
};
struct another_class
{
// note: overloaded a_func implemented as a function template
template<typename T>
void a_func(T v) const
{
std::cout <<
"another_class::void a_func(T v = " << v << ")"
" [ T = " << typeid(T).name() << " ]" << std::endl;
}
int another_func()
{
std::cout << "another_class::another_func() = 5" << std::endl;
return 5;
}
};
// both classes above can be assigned to the interface variable and their
// member functions can be called through it
int main()
{
a_class x;
another_class y;
interface_x i(x);
i.a_func(12);
i.a_func(77L);
i.another_func();
i = y;
i.a_func(13);
i.a_func(21L);
i.another_func();
}

188
example/interpreter.hpp Normal file
View File

@ -0,0 +1,188 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
//
// This example implements a simple batch-style interpreter that is capable of
// calling functions previously registered with it. The parameter types of the
// functions are used to control the parsing of the input.
//
// Implementation description
// ==========================
//
// When a function is registered, an 'invoker' template is instantiated with
// the function's type. The 'invoker' fetches a value from the 'token_parser'
// for each parameter of the function into a tuple and finally invokes the the
// function with these values as arguments. The invoker's entrypoint, which
// is a function of the callable builtin that describes the function to call and
// a reference to the 'token_parser', is partially bound to the registered
// function and put into a map so it can be found by name during parsing.
#include <map>
#include <string>
#include <stdexcept>
#include <boost/token_iterator.hpp>
#include <boost/token_functions.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/fusion/include/push_back.hpp>
#include <boost/fusion/include/cons.hpp>
#include <boost/fusion/include/invoke.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/function_types/is_nonmember_callable_builtin.hpp>
#include <boost/function_types/parameter_types.hpp>
namespace example
{
namespace fusion = boost::fusion;
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
class interpreter
{
class token_parser;
typedef boost::function<void(token_parser &)> invoker_function;
typedef std::map<std::string, invoker_function> dictionary;
dictionary map_invokers;
public:
// Registers a function with the interpreter.
template<typename Function>
typename boost::enable_if< ft::is_nonmember_callable_builtin<Function>
>::type register_function(std::string const & name, Function f);
// Parse input for functions to call.
void parse_input(std::string const & text) const;
private:
template< typename Function
, class From = typename mpl::begin< ft::parameter_types<Function> >::type
, class To = typename mpl::end< ft::parameter_types<Function> >::type
>
struct invoker;
};
class interpreter::token_parser
{
typedef boost::token_iterator_generator<
boost::char_separator<char> >::type token_iterator;
token_iterator itr_at, itr_to;
public:
token_parser(token_iterator from, token_iterator to)
: itr_at(from), itr_to(to)
{ }
private:
template<typename T>
struct remove_cv_ref
: boost::remove_cv< typename boost::remove_reference<T>::type >
{ };
public:
// Returns a token of given type.
// We just apply boost::lexical_cast to whitespace separated string tokens
// for simplicity.
template<typename RequestedType>
typename remove_cv_ref<RequestedType>::type get()
{
if (! this->has_more_tokens())
throw std::runtime_error("unexpected end of input");
try
{
typedef typename remove_cv_ref<RequestedType>::type result_type;
result_type result = boost::lexical_cast
<typename remove_cv_ref<result_type>::type>(*this->itr_at);
++this->itr_at;
return result;
}
catch (boost::bad_lexical_cast &)
{ throw std::runtime_error("invalid argument: " + *this->itr_at); }
}
// Any more tokens?
bool has_more_tokens() const { return this->itr_at != this->itr_to; }
};
template<typename Function, class From, class To>
struct interpreter::invoker
{
// add an argument to a Fusion cons-list for each parameter type
template<typename Args>
static inline
void apply(Function func, token_parser & parser, Args const & args)
{
typedef typename mpl::deref<From>::type arg_type;
invoker<Function, typename mpl::next<From>::type, To>::apply
( func, parser, fusion::push_back(args, parser.get<arg_type>()) );
}
};
template<typename Function, class To>
struct interpreter::invoker<Function,To,To>
{
// the argument list is complete, now call the function
template<typename Args>
static inline
void apply(Function func, token_parser &, Args const & args)
{
fusion::invoke(func,args);
}
};
template<typename Function>
typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> >::type
interpreter::register_function(std::string const & name, Function f)
{
// instantiate and store the invoker by name
this->map_invokers[name] = boost::bind(
& invoker<Function>::template apply<fusion::nil>, f,_1,fusion::nil() );
}
void interpreter::parse_input(std::string const & text) const
{
boost::char_separator<char> s(" \t\n\r");
token_parser parser
( boost::make_token_iterator<std::string>(text.begin(), text.end(), s)
, boost::make_token_iterator<std::string>(text.end() , text.end(), s) );
while (parser.has_more_tokens())
{
// read function name
std::string func_name = parser.get<std::string>();
// look up function
dictionary::const_iterator entry = map_invokers.find( func_name );
if (entry == map_invokers.end())
throw std::runtime_error("unknown function: " + func_name);
// call the invoker which controls argument parsing
entry->second(parser);
}
}
}

View File

@ -0,0 +1,56 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <string>
#include <iostream>
#include <stdexcept>
#include "interpreter.hpp"
void echo(std::string const & s)
{
std::cout << s << std::endl;
}
void add(int a, int b)
{
std::cout << a + b << std::endl;
}
void repeat(std::string const & s, int n)
{
while (--n >= 0) std::cout << s;
std::cout << std::endl;
}
int main()
{
example::interpreter interpreter;
interpreter.register_function("echo", & echo);
interpreter.register_function("add", & add);
interpreter.register_function("repeat", & repeat);
std::string line = "nonempty";
while (! line.empty())
{
std::cout << std::endl << "] ", std::getline(std::cin,line);
try
{
interpreter.parse_input(line);
}
catch (std::runtime_error &error)
{
std::cerr << error.what() << std::endl;
}
}
return 0;
}

View File

@ -0,0 +1,73 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
//
// This example implements a utility to accept a type expression, that may
// contain commas to a macro.
//
//
// Detailed description
// ====================
//
// Accepting a type as macro argument can cause problems if the type expression
// contains commas:
//
// #define MY_MACRO(a_type)
// ...
// MY_MACRO(std::map<int,int>) // ERROR (wrong number of macro arguments)
//
// This problem can be solved by pasing using a parenthesized type
//
// MY_MACRO((std::map<int,int>) // OK
//
// but then there is no way to remove the parentheses in the macro argument
// with the preprocessor.
// We can, however, form a pointer to a function with a single argument (the
// parentheses become part of the type) and extract the argument with template
// metaprogramming:
//
// // Inside the macro definition
//
// typename mpl::front< parameter_types<void(*)a_type> >::type
//
// This code snippet does not read too expressive so we use another macro
// to encapsulate the solution:
//
// // Inside the macro definition
//
// BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(a_type)
//
// As a generalization of this technique we can accept a comma-separated list of
// types. Omitting the mpl::front invocation gives us an MPL-sequence.
//
//
// Limitations
// ===========
//
// - only works for types that are valid function arguments
//
// Acknowledgments
// ===============
//
// Thanks go to Dave Abrahams for letting me know this technique.
#ifndef BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED
#include <boost/function_types/parameter_types.hpp>
#include <boost/mpl/front.hpp>
#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type) \
boost::mpl::front< \
BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_type) >::type
#define BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) \
::boost::function_types::parameter_types< void(*) parenthesized_types >
#endif

View File

@ -0,0 +1,71 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
// See macro_type_arugment.hpp in this directory for details.
#include <string>
#include <typeinfo>
#include <iostream>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/deref.hpp>
#include "macro_type_args.hpp"
#define TYPE_NAME(parenthesized_type) \
typeid(BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type)).name()
namespace example
{
namespace mpl = boost::mpl;
template<class Curr, class End>
struct mpl_seq_to_string_impl
{
static std::string get(std::string const & prev)
{
typedef typename mpl::next<Curr>::type next_pos;
typedef typename mpl::deref<Curr>::type type;
return mpl_seq_to_string_impl<next_pos,End>::get(
prev + (prev.empty()? '\0' : ',') + typeid(type).name() );
}
};
template<class End>
struct mpl_seq_to_string_impl<End, End>
{
static std::string get(std::string const & prev)
{
return prev;
}
};
template<class Seq>
std::string mpl_seq_to_string()
{
typedef typename mpl::begin<Seq>::type begin;
typedef typename mpl::end<Seq>::type end;
return mpl_seq_to_string_impl<begin, end>::get("");
}
}
#define TYPE_NAMES(parenthesized_types) \
::example::mpl_seq_to_string< \
BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) >()
int main()
{
std::cout << TYPE_NAME((int)) << std::endl;
std::cout << TYPE_NAMES((int,char)) << std::endl;
std::cout << TYPE_NAMES((int,char,long)) << std::endl;
}

86
example/result_of.hpp Normal file
View File

@ -0,0 +1,86 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
//
// Reimplementation of the Boost result_of utility (see [Gregor01] and
// [Gregor02]).
//
//
// Detailed description
// ====================
//
// This example implements the functionality of the Boost result_of utility.
// Because of FunctionTypes we get away without repetitive code and the Boost
// Preprocessor library.
//
//
// Bibliography
// ============
//
// [Gregor01] Gregor, D. The Boost result_of utility
// http://www.boost.org/libs/utility
//
// [Gregor02] Gregor, D. A uniform method for computing function object return
// types (revision 1)
// http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html
#include <boost/function_types/result_type.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/has_xxx.hpp>
namespace example
{
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
template<typename F> struct result_of;
namespace detail
{
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
template<typename F>
struct result_type_member
{
typedef typename F::result_type type;
};
template<typename F, typename Desc>
struct result_member_template
{
typedef typename F::template result<Desc>::type type;
};
#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
template<typename F>
struct result_member_template< F, F(void) >
{
typedef void type;
};
#endif
template<typename F, typename Desc>
struct result_of_impl
: mpl::eval_if
< ft::is_callable_builtin<F>
, ft::result_type<F>
, mpl::eval_if
< has_result_type<F>
, result_type_member<F>
, result_member_template<F,Desc>
> >
{ };
}
template<typename Desc>
struct result_of
: detail::result_of_impl< typename ft::result_type<Desc>::type, Desc >
{ };
}

View File

@ -0,0 +1,59 @@
// (C) Copyright Douglas Gregor 2003-2004.
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
// This file is a modified copy of the original Boost.ResultOf test-suite.
// See result_of.hpp in this directory for details.
#include "result_of.hpp"
#include <utility>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
struct int_result_type { typedef int result_type; };
struct int_result_of
{
template<typename F> struct result { typedef int type; };
};
struct int_result_type_and_float_result_of
{
typedef int result_type;
template<typename F> struct result { typedef float type; };
};
struct X {};
int main()
{
using namespace boost;
namespace e = example;
typedef int (*func_ptr)(float, double);
typedef int (&func_ref)(float, double);
typedef int (X::*mem_func_ptr)(float);
typedef int (X::*mem_func_ptr_c)(float) const;
typedef int (X::*mem_func_ptr_v)(float) volatile;
typedef int (X::*mem_func_ptr_cv)(float) const volatile;
BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_type(float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<const int_result_of(double)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<volatile int_result_of(void)>::type, void>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_type_and_float_result_of(char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<func_ptr(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<func_ref(char, float)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_c(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_v(X,char)>::type, int>::value));
BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
return 0;
}

14
index.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
<p>Automatic redirection failed, please go to
<a href="doc/html/index.html">doc/html/index.html</a>.</p>
<p>Copyright&nbsp;Tobias Schwinger 2005-2007</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">
LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).</p>
</body>
</html>

85
test/Jamfile Normal file
View File

@ -0,0 +1,85 @@
# (C) Copyright Tobias Schwinger
#
# Use, modification and distribution are subject to the Boost Software License,
# Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
#-------------------------------------------------------------------------------
import testing ;
{
test-suite function_types :
# Classification
[ compile classification/is_function.cpp ]
[ compile classification/is_function_pointer.cpp ]
[ compile classification/is_function_reference.cpp ]
[ compile classification/is_member_function_pointer.cpp ]
[ compile classification/is_member_object_pointer.cpp ]
[ compile classification/is_callable_builtin.cpp ]
[ compile classification/is_nonmember_callable_builtin.cpp ]
[ compile classification/is_member_pointer.cpp ]
[ compile classification/is_cv_mem_func_ptr.cpp ]
[ compile classification/is_variadic.cpp ]
[ compile classification/is_cv_pointer.cpp ]
# [ compile classification/is_cv_function.cpp ]
# Decomposition
[ compile decomposition/components.cpp ]
[ compile decomposition/result_type.cpp ]
[ compile decomposition/function_arity.cpp ]
[ compile decomposition/parameter_types.cpp ]
[ compile decomposition/components_seq.cpp ]
[ compile decomposition/class_type_transform.cpp ]
[ compile-fail decomposition/result_type_fail.cpp ]
[ compile-fail decomposition/parameter_types_fail.cpp ]
[ compile-fail decomposition/function_arity_fail.cpp ]
# Synthesis
[ compile synthesis/function_type.cpp ]
[ compile synthesis/function_pointer.cpp ]
[ compile synthesis/function_reference.cpp ]
[ compile synthesis/member_function_pointer.cpp ]
[ compile synthesis/member_object_pointer.cpp ]
[ compile synthesis/transformation.cpp ]
[ compile synthesis/mem_func_ptr_cv1.cpp ]
[ compile synthesis/mem_func_ptr_cv2.cpp ]
[ compile synthesis/mem_func_ptr_cv_ptr_to_this.cpp ]
[ compile synthesis/variadic_function_synthesis.cpp ]
# [ compile synthesis/cv_function_synthesis.cpp ]
# Reconfiguration
[ compile reconfiguration/preprocessing_mode.cpp ]
[ compile reconfiguration/partial_arity_preprocessing.cpp ]
[ compile reconfiguration/cc_preprocessing.cpp ]
# Custom calling conventions
[ compile custom_ccs/nonmember_ccs.cpp ]
[ compile custom_ccs/nonmember_ccs_exact.cpp ]
[ compile custom_ccs/member_ccs.cpp ]
[ compile custom_ccs/member_ccs_exact.cpp ]
# Code from the examples
[ compile ../example/interpreter_example.cpp ]
[ compile ../example/result_of_example.cpp ]
[ compile ../example/interface_example.cpp ]
[ compile ../example/fast_mem_fn_example.cpp
# needed for Boost.PP file iteration with some compilers
: <include>../example
]
[ compile ../example/macro_type_args_example.cpp ]
;
}

View File

@ -0,0 +1,86 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func_ref >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< c_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< v_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< int[1] >
));

View File

@ -0,0 +1,142 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_function.hpp>
namespace ft = boost::function_types;
template<typename C, typename T>
void test_non_cv(T C::*)
{
BOOST_MPL_ASSERT((
ft::is_function<T, ft::non_const >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::non_volatile >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::tag<ft::non_const,ft::non_volatile> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::const_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::volatile_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::tag<ft::const_qualified,ft::volatile_qualified> >
));
}
template<typename C, typename T>
void test_c_non_v(T C::*)
{
BOOST_MPL_ASSERT((
ft::is_function<T, ft::const_qualified >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::non_volatile >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::tag<ft::const_qualified,ft::non_volatile> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::non_const >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::volatile_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::tag<ft::non_const,ft::volatile_qualified> >
));
}
template<typename C, typename T>
void test_v_non_c(T C::*)
{
BOOST_MPL_ASSERT((
ft::is_function<T, ft::non_const >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::volatile_qualified >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::tag<ft::non_const,ft::volatile_qualified> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::const_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::non_volatile >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::tag<ft::const_qualified,ft::non_volatile> >
));
}
template<typename C, typename T>
void test_cv(T C::*)
{
BOOST_MPL_ASSERT((
ft::is_function<T, ft::const_qualified >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::volatile_qualified >
));
BOOST_MPL_ASSERT((
ft::is_function<T, ft::tag<ft::const_qualified,ft::volatile_qualified> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::non_const >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::non_volatile >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function<T, ft::tag<ft::non_const,ft::non_volatile> >
));
}
struct C
{
void non_cv(int) { }
void c_non_v(int) const { }
void v_non_c(int) volatile { }
void cv(int) const volatile { }
};
void instanitate()
{
test_non_cv(& C::non_cv);
test_c_non_v(& C::c_non_v);
test_v_non_c(& C::v_non_c);
test_cv(& C::cv);
}

View File

@ -0,0 +1,150 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
namespace ft = boost::function_types;
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_ptr, ft::non_const >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_ptr, ft::non_volatile >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_ptr,
ft::tag<ft::non_const, ft::non_volatile> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_func_ptr, ft::const_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_func_ptr, ft::volatile_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_func_ptr,
ft::tag<ft::const_qualified, ft::volatile_qualified> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_func_ptr,
ft::tag<ft::non_const, ft::volatile_qualified> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_func_ptr,
ft::tag<ft::const_qualified, ft::non_volatile> >
));
//
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< c_mem_func_ptr, ft::const_qualified >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< c_mem_func_ptr, ft::non_volatile >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< c_mem_func_ptr, ft::non_const >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< c_mem_func_ptr, ft::volatile_qualified >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< c_mem_func_ptr,
ft::tag<ft::const_qualified, ft::non_volatile> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< c_mem_func_ptr,
ft::tag<ft::non_const, ft::volatile_qualified> >
));
//
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< v_mem_func_ptr, ft::volatile_qualified >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< v_mem_func_ptr, ft::non_const >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< v_mem_func_ptr, ft::non_volatile >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< v_mem_func_ptr, ft::const_qualified >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< v_mem_func_ptr,
ft::tag<ft::non_const, ft::volatile_qualified> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< v_mem_func_ptr,
ft::tag<ft::const_qualified, ft::non_volatile> >
));
//
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< cv_mem_func_ptr, ft::const_qualified >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< cv_mem_func_ptr, ft::volatile_qualified >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< cv_mem_func_ptr, ft::non_const >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< cv_mem_func_ptr, ft::non_volatile >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< cv_mem_func_ptr,
ft::tag<ft::non_const, ft::non_volatile> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< cv_mem_func_ptr,
ft::tag<ft::const_qualified, ft::non_volatile> >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< cv_mem_func_ptr,
ft::tag<ft::non_const, ft::volatile_qualified> >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< cv_mem_func_ptr,
ft::tag<ft::const_qualified, ft::volatile_qualified> >
));

View File

@ -0,0 +1,50 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_function_pointer.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
namespace ft = boost::function_types;
typedef void(* const func_c_ptr)();
typedef void(* volatile func_v_ptr)();
typedef void(* const volatile func_cv_ptr)();
class C;
typedef void(C::* const mem_func_c_ptr)();
typedef void(C::* volatile mem_func_v_ptr)();
typedef void(C::* const volatile mem_func_cv_ptr)();
// note: the pointer has cv-qualifiers, not the function - non_cv tag must match
BOOST_MPL_ASSERT((
ft::is_function_pointer< func_c_ptr, ft::non_cv >
));
BOOST_MPL_ASSERT((
ft::is_function_pointer< func_v_ptr, ft::non_cv >
));
BOOST_MPL_ASSERT((
ft::is_function_pointer< func_cv_ptr, ft::non_cv >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_c_ptr, ft::non_cv >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_v_ptr, ft::non_cv >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_cv_ptr, ft::non_cv >
));

View File

@ -0,0 +1,87 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_function.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
BOOST_MPL_ASSERT((
ft::is_function< func >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< func_ref >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< c_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< v_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function< int[1] >
));

View File

@ -0,0 +1,87 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_function_pointer.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< func >
));
BOOST_MPL_ASSERT((
ft::is_function_pointer< func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< func_ref >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< c_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< v_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_pointer< int[1] >
));

View File

@ -0,0 +1,88 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_function_reference.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< func >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_function_reference< func_ref >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< c_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< v_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_function_reference< int[1] >
));

View File

@ -0,0 +1,96 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_member_function_pointer.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
typedef int C::*mem_ptr;
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< func >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< func_ref >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< c_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< v_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_function_pointer< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< mem_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_function_pointer< int[1] >
));

View File

@ -0,0 +1,95 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_member_object_pointer.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
typedef int C::*mem_ptr;
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< func >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< func_ref >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< c_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< v_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_object_pointer< mem_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< mem_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_object_pointer< int[1] >
));

View File

@ -0,0 +1,88 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_member_pointer.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
typedef int C::*mem_ptr;
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< func >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< func_ref >
));
BOOST_MPL_ASSERT((
ft::is_member_pointer< mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_pointer< c_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_pointer< v_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_pointer< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_member_pointer< mem_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< mem_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_member_pointer< int& >
));

View File

@ -0,0 +1,87 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_nonmember_callable_builtin.hpp>
namespace ft = boost::function_types;
typedef void func();
typedef void (*func_ptr)();
typedef void (&func_ref)();
class C;
typedef void (C::*mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)() const;
typedef void (C::*v_mem_func_ptr)() volatile;
typedef void (C::*cv_mem_func_ptr)() const volatile;
BOOST_MPL_ASSERT((
ft::is_nonmember_callable_builtin< func >
));
BOOST_MPL_ASSERT((
ft::is_nonmember_callable_builtin< func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_nonmember_callable_builtin< func_ref >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< c_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< v_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< C >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< int >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< int* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< int** >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< int& >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< int[] >
));
BOOST_MPL_ASSERT_NOT((
ft::is_nonmember_callable_builtin< int[1] >
));

View File

@ -0,0 +1,143 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
namespace ft = boost::function_types;
typedef void func(...);
typedef void nv_func();
typedef void (*func_ptr)(...);
typedef void (*nv_func_ptr)();
typedef void (&func_ref)(...);
typedef void (&nv_func_ref)();
class C;
typedef void (C::*mem_func_ptr)(...);
typedef void (C::*nv_mem_func_ptr)();
typedef void (C::*c_mem_func_ptr)(...) const;
typedef void (C::*v_mem_func_ptr)(...) volatile;
typedef void (C::*cv_mem_func_ptr)(...) const volatile;
typedef int C::* mem_ptr;
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func, ft::variadic >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< func, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< nv_func >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< nv_func, ft::variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< nv_func, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func_ptr, ft::variadic>
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< func_ptr, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< nv_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< nv_func_ptr, ft::variadic>
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< nv_func_ptr, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< func_ref >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< mem_func_ptr, ft::variadic >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< mem_func_ptr, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< nv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< nv_mem_func_ptr, ft::variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< nv_mem_func_ptr, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< c_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< v_mem_func_ptr >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< cv_mem_func_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< mem_func_ptr* >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< C, ft::variadic >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< C, ft::non_variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< mem_ptr >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< mem_ptr, ft::variadic >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< mem_ptr, ft::non_variadic >
));

View File

@ -0,0 +1,50 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_AUTODETECT_CALLING_CONVENTIONS
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/function_types/member_function_pointer.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#ifndef BOOST_FT_CC_STDCALL
# error "test not supported with this compiler"
#endif
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
typedef ft::stdcall_cc cc;
class C;
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::member_function_pointer<mpl::vector<int, C &>, cc>::type
>
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::member_function_pointer<mpl::vector<int, C const &>, cc>::type
>
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::member_function_pointer<mpl::vector<int, C volatile &>, cc>::type
>
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::member_function_pointer<mpl::vector<int, C const volatile &>, cc>::type
>
));

View File

@ -0,0 +1,71 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_AUTODETECT_CALLING_CONVENTIONS
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/function_types/member_function_pointer.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#ifndef BOOST_FT_CC_STDCALL
# error "test not supported with this compiler"
#endif
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
typedef ft::stdcall_cc cc;
typedef ft::default_cc dc;
class C;
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &>, cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const &>, cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C volatile &>, cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const volatile &>, cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &> >::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &>, cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const &>, cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C volatile &>, cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const volatile &>, cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &> >::type, cc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &>, cc>::type, dc >
));

View File

@ -0,0 +1,45 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_AUTODETECT_CALLING_CONVENTIONS
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/function_reference.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#ifndef BOOST_FT_CC_STDCALL
# error "test not supported with this compiler"
#endif
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
typedef ft::stdcall_cc cc;
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::function_type<mpl::vector<void,int>, cc>::type
>
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::function_pointer<mpl::vector<void,int>, cc>::type
>
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin<
ft::function_reference<mpl::vector<void,int>, cc>::type
>
));

View File

@ -0,0 +1,62 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_AUTODETECT_CALLING_CONVENTIONS
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/function_reference.hpp>
#include <boost/function_types/is_callable_builtin.hpp>
#ifndef BOOST_FT_CC_STDCALL
# error "test not supported with this compiler"
#endif
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
typedef ft::stdcall_cc cc;
typedef ft::default_cc dc;
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::function_type<mpl::vector<void>,cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::function_pointer<mpl::vector<void>,cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::function_reference<mpl::vector<void>,cc>::type, cc >
));
BOOST_MPL_ASSERT((
ft::is_callable_builtin< ft::function_pointer<mpl::vector<void> >::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::function_type<mpl::vector<void>, cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::function_pointer<mpl::vector<void>,cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::function_reference<mpl::vector<void>,cc>::type, dc >
));
BOOST_MPL_ASSERT_NOT((
ft::is_callable_builtin< ft::function_pointer<mpl::vector<void> >::type, cc >
));

View File

@ -0,0 +1,62 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/always.hpp>
#include <boost/function_types/components.hpp>
#include <boost/function_types/parameter_types.hpp>
using namespace boost;
namespace ft = function_types;
using boost::mpl::placeholders::_;
class C;
typedef C (C::*mem_func_ptr)();
class X;
BOOST_MPL_ASSERT((
is_same< mpl::at_c<
ft::components<mem_func_ptr, add_pointer<_> >
,1 >::type, C* >
));
BOOST_MPL_ASSERT((
is_same< mpl::at_c<
ft::components<mem_func_ptr, add_pointer< add_pointer<_> > >
,1 >::type, C** >
));
BOOST_MPL_ASSERT((
is_same< mpl::at_c<
ft::components<mem_func_ptr, mpl::always<X> >
,1 >::type, X >
));
BOOST_MPL_ASSERT((
is_same< mpl::at_c<
ft::parameter_types<mem_func_ptr, add_pointer<_> >
,0 >::type, C* >
));
BOOST_MPL_ASSERT((
is_same< mpl::at_c<
ft::parameter_types<mem_func_ptr, add_pointer< add_pointer<_> > >
,0 >::type, C** >
));
BOOST_MPL_ASSERT((
is_same< mpl::at_c<
ft::parameter_types<mem_func_ptr, mpl::always<X> >
,0 >::type, X >
));

View File

@ -0,0 +1,59 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/function_types/components.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
class C;
typedef C func();
typedef C (*func_ptr)(int);
typedef C (&func_ref)(int,int);
typedef C (C::*mem_func_ptr)();
typedef C (C::*c_mem_func_ptr)(int) const;
typedef C (C::*v_mem_func_ptr)(int,int) volatile;
typedef C (C::*cv_mem_func_ptr)(int,int,int) const volatile;
typedef int C::* mem_ptr;
BOOST_MPL_ASSERT((
mpl::equal< ft::components<func>::types, mpl::vector<C> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<func_ptr>::types, mpl::vector<C,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<func_ref>::types, mpl::vector<C,int,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<mem_func_ptr>::types, mpl::vector<C,C &> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<c_mem_func_ptr>::types, mpl::vector<C,C const &,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<v_mem_func_ptr>::types, mpl::vector<C,C volatile &,int,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<cv_mem_func_ptr>::types, mpl::vector<C,C const volatile &,int,int,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::components<mem_ptr>::types, mpl::vector<int &,C&> >
));

View File

@ -0,0 +1,75 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/pop_back.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/function_types/components.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef C (C::* mem_func_ptr)(int);
typedef ft::components<mem_func_ptr> c;
// front
BOOST_MPL_ASSERT(( is_same< ::boost::mpl::front<c>::type, C > ));
// back
BOOST_MPL_ASSERT(( is_same< ::boost::mpl::back<c>::type, int > ));
// at
BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c<c,0>::type, C > ));
BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c<c,1>::type, C & > ));
BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c<c,2>::type, int > ));
// begin/end
BOOST_MPL_ASSERT(( mpl::equal< c, mpl::vector<C,C &, int> > ));
// clear
BOOST_MPL_ASSERT(( mpl::equal< mpl::clear<c>, mpl::vector<> > ));
// push_front
BOOST_MPL_ASSERT(( mpl::equal< mpl::push_front<c,C>::type, mpl::vector<C,C,C &,int> > ));
// pop_front
BOOST_MPL_ASSERT(( mpl::equal< mpl::pop_front<c>::type, mpl::vector<C &,int> > ));
// push_back
BOOST_MPL_ASSERT(( mpl::equal< mpl::push_back<c,C>::type, mpl::vector<C,C &,int,C> > ));
// pop_back
BOOST_MPL_ASSERT(( mpl::equal< mpl::pop_back<c>::type, mpl::vector<C,C &> > ));
// size
BOOST_MPL_ASSERT_RELATION( ::boost::mpl::size<c>::value, ==, 3 );
// empty
BOOST_MPL_ASSERT_NOT(( mpl::empty<c> ));
BOOST_MPL_ASSERT(( mpl::empty< mpl::clear<c> > ));

View File

@ -0,0 +1,31 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/function_types/function_arity.hpp>
class C;
typedef C func();
typedef C (*func_ptr)(int);
typedef C (&func_ref)(int,int);
typedef C (C::*mem_func_ptr)();
typedef C (C::*c_mem_func_ptr)(int) const;
typedef C (C::*v_mem_func_ptr)(int,int) volatile;
typedef C (C::*cv_mem_func_ptr)(int,int,int) const volatile;
typedef int C::* mem_ptr;
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<func>::value, ==, 0 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<func_ptr>::value, ==, 1 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<func_ref>::value, ==, 2 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<mem_func_ptr>::value, ==, 1 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<c_mem_func_ptr>::value, ==, 2 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<v_mem_func_ptr>::value, ==, 3 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<cv_mem_func_ptr>::value, ==, 4 );
BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<mem_ptr>::value, ==, 1 );

View File

@ -0,0 +1,19 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/function_types/function_arity.hpp>
namespace ft = boost::function_types;
class C;
typedef ft::function_arity<C>::type error_1;
typedef ft::function_arity<int>::type error_2;
typedef ft::function_arity<void>::type error_3;

View File

@ -0,0 +1,59 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/function_types/parameter_types.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
class C;
typedef C func(C);
typedef C (*func_ptr)(C,int);
typedef C (&func_ref)();
typedef C (C::*mem_func_ptr)(C,int);
typedef C (C::*c_mem_func_ptr)(C,C) const;
typedef C (C::*v_mem_func_ptr)(C) volatile;
typedef C (C::*cv_mem_func_ptr)() const volatile;
typedef C C::*mem_ptr;
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<func>, mpl::vector<C> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<func_ptr>::type, mpl::vector<C,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<func_ref>, mpl::vector<> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<mem_func_ptr>, mpl::vector<C &,C,int> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<c_mem_func_ptr>, mpl::vector<C const &,C,C> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<v_mem_func_ptr>, mpl::vector<C volatile &,C> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<cv_mem_func_ptr>, mpl::vector<C const volatile &> >
));
BOOST_MPL_ASSERT((
mpl::equal< ft::parameter_types<mem_ptr>, mpl::vector<C &> >
));

View File

@ -0,0 +1,19 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/function_types/parameter_types.hpp>
namespace ft = boost::function_types;
class C;
typedef ft::parameter_types<C>::type error_1;
typedef ft::parameter_types<char>::type error_2;
typedef ft::parameter_types<void>::type error_3;

View File

@ -0,0 +1,63 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/result_type.hpp>
namespace ft = boost::function_types;
class C;
typedef C func();
typedef C (*func_ptr)();
typedef C (&func_ref)();
typedef C (C::*mem_func_ptr)();
typedef C (C::*c_mem_func_ptr)() const;
typedef C (C::*v_mem_func_ptr)() volatile;
typedef C (C::*cv_mem_func_ptr)() const volatile;
typedef int C::* mem_ptr;
typedef int const C::* c_mem_ptr;
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<func>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<func_ptr>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<func_ref>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<mem_func_ptr>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<c_mem_func_ptr>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<v_mem_func_ptr>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<cv_mem_func_ptr>::type,C>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<mem_ptr>::type,int&>
));
BOOST_MPL_ASSERT((
boost::is_same<ft::result_type<c_mem_ptr>::type,int const&>
));

View File

@ -0,0 +1,19 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/function_types/result_type.hpp>
namespace ft = boost::function_types;
class C;
typedef ft::result_type<C>::type error_1;
typedef ft::result_type<char>::type error_2;
typedef ft::result_type<void>::type error_3;

View File

@ -0,0 +1,11 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_CC_PREPROCESSING 1
#include "simple_test.hpp"

View File

@ -0,0 +1,11 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_MAX_ARITY 19
#include "simple_test.hpp"

View File

@ -0,0 +1,11 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#define BOOST_FT_PREPROCESSING_MODE 1
#include "simple_test.hpp"

View File

@ -0,0 +1,51 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
class C;
typedef void func(C &);
typedef int (C::* mem_func_ptr)(int);
typedef ft::components<func> func_components;
typedef ft::components<mem_func_ptr> mfp_components;
BOOST_MPL_ASSERT((
mpl::equal< func_components::types, mpl::vector<void,C &> >
));
BOOST_MPL_ASSERT_RELATION(
::func_components::function_arity::value, ==, 1
);
BOOST_MPL_ASSERT((
boost::is_same< ft::function_type< mpl::vector<void,C &> >::type, func >
));
BOOST_MPL_ASSERT((
mpl::equal< mfp_components::types, mpl::vector<int,C &,int> >
));
BOOST_MPL_ASSERT_RELATION(
::mfp_components::function_arity::value, ==, 2
);
BOOST_MPL_ASSERT((
boost::is_same< ft::member_function_pointer< mpl::vector<int,C &,int> >::type, mem_func_ptr >
));

View File

@ -0,0 +1,249 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/function_type.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
template<typename C, typename T>
void test_non_cv(T C::*)
{
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_const >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::volatile_qualified> >::type
, T
>));
BOOST_MPL_ASSERT_NOT((
boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::volatile_qualified> >::type
, T
>));
}
template<typename C, typename T>
void test_c_non_v(T C::*)
{
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_const >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int> >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::volatile_qualified> >::type
, T
>));
BOOST_MPL_ASSERT_NOT((
boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::volatile_qualified> >::type
, T
>));
}
template<typename C, typename T>
void test_v_non_c(T C::*)
{
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_const >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::volatile_qualified> >::type
, T
>));
BOOST_MPL_ASSERT((
boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::volatile_qualified> >::type
, T
>));
}
template<typename C, typename T>
void test_cv(T C::*)
{
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_const >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::non_volatile> >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type
, T
>));
BOOST_MPL_ASSERT_NOT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::non_const,ft::volatile_qualified> >::type
, T
>));
BOOST_MPL_ASSERT_NOT((
boost::is_same<
ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type
, T
>));
BOOST_MPL_ASSERT(( boost::is_same<
ft::function_type< mpl::vector<void,int>,
ft::tag<ft::const_qualified,ft::volatile_qualified> >::type
, T
>));
}
struct C
{
void non_cv(int) { }
void c_non_v(int) const { }
void v_non_c(int) volatile { }
void cv(int) const volatile { }
};
void instanitate()
{
test_non_cv(& C::non_cv);
test_c_non_v(& C::c_non_v);
test_v_non_c(& C::v_non_c);
test_cv(& C::cv);
}

View File

@ -0,0 +1,24 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
typedef int (* expected)(int,int);
BOOST_MPL_ASSERT((
is_same< ft::function_pointer< mpl::vector<int,int,int> >::type, expected >
));

View File

@ -0,0 +1,24 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/function_reference.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
typedef int (& expected)(int);
BOOST_MPL_ASSERT((
is_same< ft::function_reference< mpl::vector<int,int> >::type, expected >
));

View File

@ -0,0 +1,23 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/function_type.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
typedef int expected(int,int);
BOOST_MPL_ASSERT((
is_same< ft::function_type< mpl::vector<int,int,int> >::type, expected >
));

View File

@ -0,0 +1,94 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef int (C::* expected1)(int);
typedef int (C::* expected2)(int) const;
typedef int (C::* expected3)(int) volatile;
typedef int (C::* expected4)(int) const volatile;
// implicitly specified cv qualification
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int> >::type
, expected1 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const,int> >::type
, expected2 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer<
mpl::vector<int,C volatile,int> >::type
, expected3 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer<
mpl::vector<int,C const volatile,int> >::type
, expected4 >
));
// implicit & explicit/overrides
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer<
mpl::vector<int,C const volatile,int>
, ft::tag<ft::non_const, ft::non_volatile> >::type
, expected1 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C volatile,int>,
ft::tag<ft::const_qualified, ft::non_volatile> >::type
, expected2 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const,int>,
ft::tag<ft::non_const, ft::volatile_qualified> >::type
, expected3 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const,int>,
ft::tag<ft::const_qualified, ft::volatile_qualified> >::type
, expected4 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C volatile,int>,
ft::tag<ft::const_qualified, ft::volatile_qualified> >::type
, expected4 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C volatile,int>
, ft::const_qualified >::type
, expected4 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const,int>
, ft::volatile_qualified >::type
, expected4 >
));

View File

@ -0,0 +1,94 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef int (C::* expected1)(int);
typedef int (C::* expected2)(int) const;
typedef int (C::* expected3)(int) volatile;
typedef int (C::* expected4)(int) const volatile;
// implicitly specified cv qualification
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C &,int> >::type
, expected1 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const &,int> >::type
, expected2 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer<
mpl::vector<int,C volatile &,int> >::type
, expected3 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer<
mpl::vector<int,C const volatile &,int> >::type
, expected4 >
));
// implicit & explicit/overrides
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer<
mpl::vector<int,C const volatile &,int>
, ft::tag<ft::non_const, ft::non_volatile> >::type
, expected1 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C volatile &,int>,
ft::tag<ft::const_qualified, ft::non_volatile> >::type
, expected2 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const &,int>,
ft::tag<ft::non_const, ft::volatile_qualified> >::type
, expected3 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const &,int>,
ft::tag<ft::const_qualified, ft::volatile_qualified> >::type
, expected4 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C volatile &,int>,
ft::tag<ft::const_qualified, ft::volatile_qualified> >::type
, expected4 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C volatile &,int>
, ft::const_qualified >::type
, expected4 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C const &,int>
, ft::volatile_qualified >::type
, expected4 >
));

View File

@ -0,0 +1,37 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef int (C::* expected)();
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C * const> >::type
, expected >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C * volatile> >::type
, expected >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C * const volatile> >::type
, expected >
));

View File

@ -0,0 +1,66 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef int (C::* expected1)(int);
typedef int (C::* expected2)(int) const;
typedef int (C::* expected3)(int) volatile;
typedef int (C::* expected4)(int) const volatile;
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int> >::type
, expected1 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int>,
ft::tag<ft::non_const, ft::non_volatile> >::type
, expected1 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int>
, ft::const_qualified >::type
, expected2 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int>,
ft::tag<ft::const_qualified, ft::non_volatile> >::type
, expected2 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int>
, ft::volatile_qualified >::type
, expected3 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int>,
ft::tag<ft::non_const, ft::volatile_qualified> >::type
, expected3 >
));
BOOST_MPL_ASSERT((
is_same< ft::member_function_pointer< mpl::vector<int,C,int>,
ft::tag<ft::const_qualified, ft::volatile_qualified> >::type
, expected4 >
));

View File

@ -0,0 +1,27 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/member_object_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef int C::* expected;
BOOST_MPL_ASSERT((
is_same< ft::member_object_pointer< mpl::vector<int,C> >::type
, expected >
));

View File

@ -0,0 +1,75 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/function_reference.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef C func1(C &);
typedef C (*func_ptr1)(C &);
typedef C (&func_ref1)(C &);
typedef C (C::*mem_func_ptr1)();
BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<func1>::type > ));
BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<func_ref1>::type > ));
BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<mem_func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<func1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<func_ref1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<mem_func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<func1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<func_ref1>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<mem_func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<func1>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<func_ptr1>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<func_ref1>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<mem_func_ptr1>::type > ));
typedef C func2(C const &);
typedef C (*func_ptr2)(C const &);
typedef C (&func_ref2)(C const &);
typedef C (C::*mem_func_ptr2)() const;
BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<func2>::type > ));
BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<func_ref2>::type > ));
BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<mem_func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<func2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<func_ref2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<mem_func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<func2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<func_ref2>::type > ));
BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<mem_func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<func2>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<func_ptr2>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<func_ref2>::type > ));
BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<mem_func_ptr2>::type > ));

View File

@ -0,0 +1,63 @@
// (C) Copyright Tobias Schwinger
//
// Use modification and distribution are subject to the boost Software License,
// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt).
//------------------------------------------------------------------------------
#include <boost/mpl/assert.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/function_types/function_type.hpp>
#include <boost/function_types/function_pointer.hpp>
#include <boost/function_types/function_reference.hpp>
#include <boost/function_types/member_function_pointer.hpp>
namespace ft = boost::function_types;
namespace mpl = boost::mpl;
using boost::is_same;
class C;
typedef int expected_v_1(...);
typedef int expected_nv_1();
typedef int (C::*expected_v_2)(...);
typedef int (C::*expected_nv_2)();
BOOST_MPL_ASSERT(( is_same<
ft::function_type<mpl::vector<int>, ft::variadic>::type, expected_v_1
> ));
BOOST_MPL_ASSERT(( is_same<
ft::function_type<mpl::vector<int>, ft::non_variadic>::type, expected_nv_1
> ));
BOOST_MPL_ASSERT(( is_same<
ft::function_pointer<mpl::vector<int>, ft::variadic>::type, expected_v_1 *
> ));
BOOST_MPL_ASSERT(( is_same<
ft::function_pointer<mpl::vector<int>, ft::non_variadic>::type
, expected_nv_1 *
> ));
BOOST_MPL_ASSERT(( is_same<
ft::function_reference<mpl::vector<int>, ft::variadic>::type, expected_v_1 &
> ));
BOOST_MPL_ASSERT(( is_same<
ft::function_reference<mpl::vector<int>, ft::non_variadic>::type
, expected_nv_1 &
> ));
BOOST_MPL_ASSERT(( is_same<
ft::member_function_pointer<mpl::vector<int,C>, ft::variadic>::type
, expected_v_2
> ));
BOOST_MPL_ASSERT(( is_same<
ft::member_function_pointer<mpl::vector<int,C>, ft::non_variadic>::type
, expected_nv_2
> ));