diff --git a/build/Jamfile b/build/Jamfile new file mode 100644 index 0000000..ce5fb17 --- /dev/null +++ b/build/Jamfile @@ -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 + ; + diff --git a/build/preprocess_arity_loops.cpp b/build/preprocess_arity_loops.cpp new file mode 100644 index 0000000..a045e9f --- /dev/null +++ b/build/preprocess_arity_loops.cpp @@ -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 +# include + +# if BOOST_PP_NIL // enable dependency scanning for dynamically included files +# include +# include +# include +# include +# 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 +# undef BOOST_FT_MAX_ARITY + +#endif + diff --git a/build/preprocess_cc_names.cpp b/build/preprocess_cc_names.cpp new file mode 100644 index 0000000..39d77c5 --- /dev/null +++ b/build/preprocess_cc_names.cpp @@ -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 +#pragma wave option(output: null) +#undef BOOST_FT_OUT_FILE + diff --git a/build/preprocess_encoding.cpp b/build/preprocess_encoding.cpp new file mode 100644 index 0000000..e2e4a5e --- /dev/null +++ b/build/preprocess_encoding.cpp @@ -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 +#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 +#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 +#pragma wave option(output: null) + +#undef BOOST_FT_OUT_FILE + + diff --git a/build/timestamps/arity_loops b/build/timestamps/arity_loops new file mode 100644 index 0000000..f91091c --- /dev/null +++ b/build/timestamps/arity_loops @@ -0,0 +1 @@ +timestamp file diff --git a/build/timestamps/cc_names b/build/timestamps/cc_names new file mode 100644 index 0000000..e33ac14 --- /dev/null +++ b/build/timestamps/cc_names @@ -0,0 +1,2 @@ +timestamp file + diff --git a/build/timestamps/encoding b/build/timestamps/encoding new file mode 100644 index 0000000..f91091c --- /dev/null +++ b/build/timestamps/encoding @@ -0,0 +1 @@ +timestamp file diff --git a/doc/Jamfile b/doc/Jamfile new file mode 100644 index 0000000..5b46953 --- /dev/null +++ b/doc/Jamfile @@ -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 + : + boost.root=../../../.. + boost.libraries=../../../libraries.htm + chunk.first.sections=1 + chunk.section.depth=2 + generate.section.toc.level=2 + toc.section.depth=1 + toc.max.depth=1 + ; + diff --git a/doc/function_types.qbk b/doc/function_types.qbk new file mode 100644 index 0000000..0f989ae --- /dev/null +++ b/doc/function_types.qbk @@ -0,0 +1,1104 @@ +[library Boost.FunctionTypes + [quickbook 1.3] + [version 2.5] + [authors [Schwinger, Tobias]] + [copyright 2004-2007 Tobias Schwinger] + [license + Distributed under 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]) + ] + [purpose Meta-programming support library] + [category template] + [category generic] + [last-revision $Date$] +] + +[def __unspecified__ /unspecified/] + +[def __mpl__ [@../../../mpl/index.html MPL]] +[def __mpl_integral_constant__ __mpl__ - [@../../../mpl/doc/refmanual/integral-constant.html Integral Constant]] +[def __mpl_fwd_seq__ __mpl__ - [@../../../mpl/doc/refmanual/forward-sequence.html Forward Sequence]] +[def __mpl_fb_ext_ra_seq__ __mpl__ - [@../../../mpl/doc/refmanual/front-extensible-sequence.html Front] / [@../../../mpl/doc/refmanual/back-extensible-sequence.html Back ][@../../../mpl/doc/refmanual/extensible-sequence.html Extensible ][@../../../mpl/doc/refmanual/random-access-sequence.html Random Access Sequence]] +[def __mpl_lambda_expression__ __mpl__ - [@../../../mpl/doc/refmanual/lambda-expression.html Lambda Expression]] + +[def __is_function [link boost_functiontypes.reference.classification.is_function is_function]] +[def __is_function_pointer [link boost_functiontypes.reference.classification.is_function_pointer is_function_pointer]] +[def __is_function_reference [link boost_functiontypes.reference.classification.is_function_reference is_function_reference]] +[def __is_member_function_pointer [link boost_functiontypes.reference.classification.is_member_function_pointer is_member_function_pointer]] +[def __is_callable_builtin [link boost_functiontypes.reference.classification.is_callable_builtin is_callable_builtin]] +[def __is_nonmember_callable_builtin [link boost_functiontypes.reference.classification.is_nonmember_callable_builtin is_nonmember_callable_builtin]] + +[def __components [link boost_functiontypes.reference.decomposition.components components]] +[def __parameter_types [link boost_functiontypes.reference.decomposition.parameter_types parameter_types]] +[def __function_arity [link boost_functiontypes.reference.decomposition.function_arity function_arity]] +[def __result_type [link boost_functiontypes.reference.decomposition.result_type result_type]] + +[def __function_type [link boost_functiontypes.reference.synthesis.function_type function_type]] +[def __function_pointer [link boost_functiontypes.reference.synthesis.function_pointer function_pointer]] +[def __function_reference [link boost_functiontypes.reference.synthesis.function_reference function_reference] +[def __member_function_pointer [link boost_functiontypes.reference.synthesis.member_function_pointer member_function_pointer]] + +[def __null_tag [link boost_functiontypes.reference.tag_types.null_tag null_tag]] + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:introduction Introduction] + +Boost.FunctionTypes provides functionality to classify, decompose and synthesize +function, function pointer, function reference and pointer to member types. + +We collectively refer to these types as /callable builtin/ types. + +In particular, the library can be used to: + +* test whether a type is a specific callable, builtin type, +* extract all component properties from callable, builtin types, and +* create callable, builtin types from specified properties. + +The library is designed to work well with other Boost libraries and uses +well-accepted concepts introduced by Boost and TR1. + +Templates that encapsulate boolean or numeric properties define a static member +constant called [^value]. + + __is_function_pointer< bool(*)(int) >::value // == true + + __function_arity< bool(*)(int) >::value // == 1 + +Templates that encapsulate properties that are single types contain a type +member called [^type]. + + __function_type< mpl::vector >::type // is bool(int) + + __result_type< bool(&)(int) >::type // is bool + +Templates that encapsulate properties that are type lists model an +MPL-compatible type sequence. + + __parameter_types< bool(int) > // models an MPL sequence + +[endsect] + +[section:use_cases Use Cases] + +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 [^const]/[^volatile]-qualifiers, +a function may take a variable number of (additional, POD-typed) arguments (such +as [^printf]) and several C++ implementations encode a calling convention with +each function's type to allow calls across language or (sub-)system boundaries. + + template + void accept_function(R(* func)()); + + template + void accept_function(R(& func)()); + + template + void accept_function(R(C::* func)()); + + template + void accept_function(R(C::* func)() const); + + template + void accept_function(R(C::* func)() volatile); + + template + void accept_function(R(C::* func)() const volatile); + + template + void accept_function(R(* func)(...)); + + template + void accept_function(R(& func)(...)); + + template + void accept_function(R(C::* func)(...)); + + template + void accept_function(R(C::* func)(...) const); + + template + void accept_function(R(C::* func)(...) volatile); + + template + void accept_function(R(C::* func)(...) const volatile); + + // ... + + // needs to be repeated for every additional function parameter + // times the number of possible calling conventions + +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. + +Using Boost.FunctionTypes it is possible to write a single function template +instead: + + template + void accept_function(F f) + { + // ... use Boost.FunctionTypes to analyse F + } + +The combination with a tuples library that provides an invoker component, such +as [@../../../fusion/index.html Boost.Fusion], allows to build flexible callback +facilities that are entirely free of repetitive code as shown by the +[@../../../function_types/example/interpreter.hpp interpreter example]. + +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 [^float(float)] +overload of [^std::abs]. + + float (*ptr_absf)(float) = & std::abs; + + + void foo(float(*func)(float)); + + void bar() + { + foo(& std::abs); + } + + + std::transform(b, e, o, static_cast(& std::abs)); + +The library's type synthesis capabilities can be used to automate overload +selection and instantiation of function templates. Given an overloaded function +template + + template + R overloaded(T0); + + template + R overloaded(T0,T1); + + template + R overloaded(T0,T1,T2); + +we can pick any of the three overloads and instantiate the template with +template arguments from a type sequence in a single expression: + + static_cast<__function_pointer::type>(& overloaded) + +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 +[@../../../function_types/example/interface.hpp interface example]. + +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 [@../../../function_types/example/fast_mem_fn.hpp fast_mem_fn example] +exploits this characteristic and implements a potentially inlining version of +[@../../../bind/mem_fn.html boost::mem_fn] +limited to member functions that are known at compile time. + +[endsect] + + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] +[section:about_tag_types About Tag Types] + +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. + +These tags can be used to determine whether one property of a type has a +particular value. + + is_function::value // == true + is_function::value // == false + +A compound property tag describes a combination of possible values of different +properties. +The type [^components], where [^F] is a callable builtin type, is a compound +property tag that describes [^F]. +The [^tag] class template can be used to combine property tags. + + tag // combination of two properties + +When several values for the same property are specified in [^tag]'s argument +list, only the rightmost one is used; others are ignored. + + tag, default_cc> // overrides F's calling convention property + +When compound property tag is specified to analyse a type, all of its component +properties must match. + + is_member_function_pointer< F, tag >::value + // true for + // F = void(a_class::*)() const + // false for + // F = void(a_class::*)() + // F = void(__fastcall a_class::*)() const + +Default values are selected for properties not specified by the tag in the +context of type synthesis. + + // given S = mpl::vector + + member_function_pointer::type // is int (a_class::*)() const + // note: the cv-qualification is picked based on the class type, + // a nonvariadic signature and the default calling convention + // are used + + member_function_pointer::type // is int (a_class::*)() + // no const qualification, as explicitly specified by the tag type + +[endsect] + + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:reference Reference] + + +[section:classification Class templates for type classification] + +[section:is_function is_function] + + template + struct is_function; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_function]][Predicate value as __mpl_integral_constant__]] + [[[^is_function::value]][Constant boolean value]] +] + +Determines whether a given type is a function, possibly with +additional properties as specified by a property tag. + +[endsect] + + +[section:is_function_pointer is_function_pointer] + + template + struct is_function_pointer; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_function_pointer]][Predicate value __mpl_integral_constant__]] + [[[^is_function_pointer::value]][Constant boolean value]] +] + +Determines whether a given type is a function pointer, possibly with +additional properties as specified by a property tag. + +[endsect] + + +[section:is_function_reference is_function_reference] + + template + struct is_function_reference; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_function_reference]][Predicate value __mpl_integral_constant__]] + [[[^is_function_reference::value]][Constant boolean value]] +] + +Determines whether a given type is a function reference, possibly with +additional properties as specified by a property tag. + +[endsect] + + +[section:is_member_pointer is_member_pointer] + + template + struct is_member_pointer; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_member_pointer]][Predicate value __mpl_integral_constant__]] + [[[^is_member_pointer::value]][Constant boolean value]] +] + +Determines whether a given type is a pointer to member (object or function) +type, possibly with additional properties as specified by a property tag. + +[endsect] + + +[section:is_member_object_pointer is_member_object_pointer] + + template + struct is_member_object_pointer; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^is_member_object_pointer]][Predicate value __mpl_integral_constant__]] + [[[^is_member_object_pointer::value]][Constant boolean value]] +] + +Determines whether a given type is a pointer to member object type. + +[endsect] + + +[section:is_member_function_pointer is_member_function_pointer] + + template + struct is_member_function_pointer; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_member_function_pointer]][Predicate value __mpl_integral_constant__]] + [[[^is_member_function_pointer::value]][Constant boolean value]] +] + +Determines whether a given type is a member function pointer, possibly with +additional properties as specified by a property tag. + +[endsect] + + +[section:is_callable_builtin is_callable_builtin] + + template + struct is_callable_builtin; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_callable_builtin]][Predicate value as __mpl_integral_constant__]] + [[[^is_callable_builtin::value]][Constant boolean value]] +] + +Determines whether a given type is a callable builtin, possibly with +additional properties as specified by a property tag. + +[endsect] + + + +[section:is_nonmember_callable_builtin is_nonmember_callable_builtin] + + template + struct is_nonmember_callable_builtin; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^Tag]][Further properties required for a positive result]] + [[[^is_nonmember_callable_builtin]][Predicate value as __mpl_integral_constant__]] + [[[^is_nonmember_callable_builtin::value]][Constant boolean value]] +] + +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. + +[endsect] + + +[endsect] [/ Class templates for type classification ] + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:decomposition Class templates for type decomposition] + + +[section:result_type result_type] + + template + struct result_type; + +[*Header] + + #include + +[variablelist + [[[^F]][Type to analyze]] + [[[^result_type::type]][Result type of [^F]]] +] + +Extracts the result type of a callable, builtin type. + +If [^F] is no callable, builtin type, any attempt to access the +[^type] member results in a compile error. + +[endsect] + + +[section:parameter_types parameter_types] + + template > + struct parameter_types; + +[*Header] + + #include + +[variablelist + [[[^F]][Type to analyze]] + [[[^ClassTransform]] + [__mpl_lambda_expression__ to transform the + class type if [^F] is a member function pointer]] + + [[[^parameter_types]] + [__mpl_fb_ext_ra_seq__ of parameter types]] +] + +Extracts the parameter types of a callable, builtin type. + +If [^F] is no callable, builtin type, any attempt to access the +sequence results in a compile error. + +[endsect] + + +[section:function_arity function_arity] + + template + struct function_arity; + +[*Header] + + #include + +[variablelist + [[[^F]][Callable builtin type]] + [[[^function_arity]][Function arity as __mpl_integral_constant__]] + [[[^function_arity::value]][Constant value of the function arity]] +] + +Extracts the function arity, that is the number of parameters. +The hidden [^this] of member function pointers counts, in other words +the arity value is always greater than or equal to one if [^F] is a +member function pointer. + +If [^F] is no callable, builtin type, any attempt to access the +value results in a compile error. + +[endsect] + + +[section:components components] + + template > + struct components; + +[*Header] + + #include + +[variablelist + [[[^T]][Type to analyze]] + [[[^ClassTransform]] + [__mpl_lambda_expression__ to transform the + class type if [^T] is a member function pointer]] + + [[[^components]] + [__mpl_fb_ext_ra_seq__ of all + component types and property tag]] + [[[^components::types]] + [Decorated MPL Sequence, exposed for optimization]] +] + +Extracts all properties of a callable builtin type, that is the result type, +followed by the parameter types (including the type of [^this] for member +function pointers). + +If [^T] is no callable builtin type, the component types are an empty +sequence and the Tag's meaning is equivalent to the [^__null_tag]. + +[endsect] + +[endsect] [/ Class templates for type decomposition] + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:synthesis Class templates for type synthesis] + + +[section:function_type function_type] + + template + struct function_type; + +[*Header] + + #include + +[variablelist + [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] + [[[^Tag]][Further properties]] + [[[^function_type::type]][Synthesized type]] +] + +Synthesizes a function type from given properties. + +If the template parameters do not describe a valid type, any attempt +to access the [^type] member will result in a compile error. + +[endsect] + + +[section:function_pointer function_pointer] + + template + struct function_pointer; + +[*Header] + + #include + +[variablelist + [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] + [[[^Tag]][Further properties]] + [[[^function_pointer::type]][Synthesized type]] +] + +Synthesizes a function pointer type from given properties. + +If the template parameters do not describe a valid type, any attempt +to access the [^type] member will result in a compile error. + +[endsect] + + +[section:function_reference function_reference] + + template + struct function_reference; + +[*Header] + + #include + +[variablelist + [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] + [[[^Tag]][Further properties]] + [[[^function_reference::type]][Synthesized type]] +] + +Synthesizes a function reference type from given properties. + +If the template parameters do not describe a valid type, any attempt +to access the [^type] member will result in a compile error. + +[endsect] + + +[section:member_function_pointer member_function_pointer] + + template + struct member_function_pointer; + +[*Header] + + #include + +[variablelist + [[[^Types]][Component types in form of an __mpl_fwd_seq__ or another callable, builtin type]] + [[[^Tag]][Further properties]] + [[[^member_function_pointer::type]][Synthesized type]] +] + +Synthesizes a member function pointer type from given properties. + +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. + +If the template parameters do not describe a valid type, any attempt +to access the [^type] member will result in a compile error. + +[endsect] + + +[endsect] [/ Class templates for type synthesis ] + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:tag_types Tag Types] + +[section:variadic variadic] + + typedef __unspecified__ variadic; + +[*Header] + + #include + +States that a function type takes a variable number of arguments through +an ellipsis parameter (such as [^printf]). + +[endsect] + +[section:non_variadic non_variadic] + + typedef __unspecified__ non_variadic; + +[*Header] + + #include + +States that a function type does not have an ellipsis parameter. + +[endsect] + +[section:default_cc default_cc] + + typedef __unspecified__ default_cc; + +[*Header] + + #include + +States that a function type encodes the default calling convention. + +[endsect] + +[section:const_qualified const_qualified] + + typedef __unspecified__ const_qualified; + +[*Header] + + #include + +States that a function type is const qualified. + +[endsect] + +[section:non_const non_const] + + typedef __unspecified__ non_const; + +[*Header] + + #include + +States that a function type is not const qualified. + +[endsect] + +[section:volatile_qualified volatile_qualified] + + typedef __unspecified__ volatile_qualified; + +[*Header] + + #include + +States that a function type is volatile qualified. + +[endsect] + +[section:non_volatile non_volatile] + + typedef __unspecified__ non_volatile; + +[*Header] + + #include + +States that a function type is not volatile qualified. + +[endsect] + +[section:non_cv non_cv] + + typedef __unspecified__ non_cv; + +[*Header] + + #include + +States that a function type is neither const nor volatile qualified. +Equivalent to `__tag<__non_const,__non_volatile>`, but involves +fewer template instantiations when evaluated. + +[endsect] + +[section:const_non_volatile const_non_volatile] + + typedef __unspecified__ const_non_volatile; + +[*Header] + + #include + +States that a function type is const but not volatile qualified. +Equivalent to `__tag<__const_qualified,__non_volatile>`, but involves +fewer template instantiations when evaluated. + +[endsect] + +[section:volatile_non_const volatile_non_const] + + typedef __unspecified__ volatile_non_const; + +[*Header] + + #include + +States that a function type is volatile but not const qualified. +Equivalent to `__tag<__volatile_qualified,__non_const>`, but involves +fewer template instantiations when evaluated. + +[endsect] + +[section:cv_qualfied cv_qualfied] + + typedef __unspecified__ cv_qualified; + +[*Header] + + #include + +States that a function type is both const and volatile qualified. +Equivalent to `__tag<__const_qualified,__volatile_qualified>`, but involves +fewer template instantiations when evaluated. + +[endsect] + +[section:null_tag null_tag] + + typedef __unspecified__ null_tag; + +[*Header] + + #include + +States nothing. + +[endsect] + +[section:tag tag] + + template + struct tag; + +[*Header] + + #include + +[variablelist + [[[^Tag['N]]][Property tag]] + [[[^tag]][Compound property tag]] +] + +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. + +[endsect] + +[endsect] [/ Tag Types] + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:macros Macros] + +[section:BOOST_FT_MAX_ARITY BOOST_FT_MAX_ARITY] + +Expands to a numeric value that describes the maximum function arity +supported by the library. + +Defaults to 20 if not explicitly defined by the user before inclusion +of the first library header. + +[endsect] + + + +[*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 [^boost/function_types/config/compiler.hpp].] + + +[section:BOOST_FT_CC_NAMES BOOST_FT_CC_NAMES] + +Expands to a [@../../../preprocessor/doc/data/sequences.html sequence] of +ternary [@../../../preprocessor/doc/data/tuples.html tuples] (these data +types are defined in the [@../../../preprocessor/doc/index.html +documentation of the Boost Preprocessor library]). +Each sequence element describes one calling convention specifier. +The first element in each tuple is the macro suffix for +[link boost_functiontypes.reference.macros.BOOST_FT_CC [^BOOST_FT\_CC\_*]], +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 [@../../../preprocessor/doc/ref/empty.html [^BOOST_PP_EMPTY]] or +[@../../../preprocessor/doc/ref/identity.html [^BOOST_PP_IDENTITY]][^(['name])]. + +Define this macro to extend the set of possible names for custom calling +conventions. The macro expands to nothing by default. + +The following names are predefined by the library and must not occur in the +definition of [^BOOST_FT_CC_NAMES]: + + #define BOOST_FT_BUILTIN_CC_NAMES \ + (( IMPLICIT , implicit_cc , BOOST_PP_EMPTY ))\ + (( CDECL , cdecl_cc , BOOST_PP_IDENTITY(__cdecl ) ))\ + (( STDCALL , stdcall_cc , BOOST_PP_IDENTITY(__stdcall ) ))\ + (( PASCAL , pascal_cc , BOOST_PP_IDENTITY(pascal ) ))\ + (( FASTCALL , fastcall_cc , BOOST_PP_IDENTITY(__fastcall) ))\ + (( CLRCALL , clrcall_cc , BOOST_PP_IDENTITY(__clrcall ) ))\ + (( THISCALL , thiscall_cc , BOOST_PP_IDENTITY(__thiscall) ))\ + (( IMPLICIT_THISCALL , thiscall_cc , BOOST_PP_EMPTY )) + // Don't get confused by the last line, here (thiscall can't be specified + // explicitly prior to MSVC 8). + +[endsect] + +[section:BOOST_FT_CC BOOST_FT\_CC\_*] + +Enables a specific calling convention. * dentoes the macro suffix, as +defined by +[link boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES [^BOOST_FT_CC_NAMES]] +or +[link boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES [^BOOST_FT_BUILTIN_CC_NAMES]]. + +The macro expands to a list of restrictions, separated by the [^|] character. +Possible items are: + +* callable_builtin +* member +* non_member +* variadic +* non_variadic + +If no such macro is defined for a particular calling convention, it is disabled. +Example: + + #define BOOST_FT_CC_STDCALL non_variadic|callable_builtin + // enables stdcall calling convention for all non-variadic, + // callable, builtin types + +[endsect] + +[section:BOOST_FT_COMMON_X86_CCs BOOST_FT_COMMON_X86_CCs] + +Defining this macro causes the following macros to be defined, if not defined +already: + + #define BOOST_FT_CC_CDECL BOOST_FT_COMMON_X86_CCs + #define BOOST_FT_CC_STDCALL non_variadic|BOOST_FT_COMMON_X86_CCs + #define BOOST_FT_CC_FASTCALL non_variadic|BOOST_FT_COMMON_X86_CCs + +[endsect] + +[section:BOOST_FT_SYNTAX BOOST_FT_SYNTAX] + +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. + +The default definition is as follows: + + #define BOOST_FT_SYNTAX(result,lparen,cc_spec,type_mod,name,rparen) \ + result() lparen() cc_spec() type_mod() name() rparen() + +[endsect] + +[section:BOOST_FT_NULLARY_PARAM BOOST_FT_NULLARY_PARAM] + +Set to [^void] for compilers that insist on a [^void] parameter for +nullary function types, empty by default. + +[endsect] + +[section:BOOST_FT_NO_CV_FUNC_SUPPORT BOOST_FT_NO_CV_FUNC_SUPPORT] + +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 [^1] until the standard changes, setting this macro +to [^0] may not work. + +[endsect] + + + +[*The following macros are useful for testing when changing the source code of +the library.] + + + +[section:BOOST_FT_PREPROCESSING_MODE BOOST_FT_PREPROCESSING_MODE] + +Makes the compiler preprocess as much as possible of the library code +(rather than loading already-preprocessed header files) if defined. + +[endsect] + +[section:BOOST_FT_CC_PREPROCESSING BOOST_FT_CC_PREPROCESSING] + +Makes the compiler preprocess the loop over possible names for custom +calling conventions (rather than loading an already-preprocessed header +file) if defined. + +This macro is defined automatically if +[link boost_functiontypes.reference.macros.BOOST_FT_CC_NAMES [^BOOST_FT_CC_NAMES]] +has been defined. + +[endsect] + +[endsect] + +[endsect] + +[/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ] + +[section:rationale Rationale] + +[heading Error handling rationale] + +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. + +The library's components have limited error conditions, so problematic +input can be spotted easily. + + +[heading Why MPL Sequences?] + +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 +[@../../../function/index.html [^boost::function]] after applying +[@../../../bind/index.html [^boost::bind]]) can be expressed more +easily. The MPL Sequence concept is compatible with several other Boost +libraries (most importantly [@../../../fusion/index.html Fusion]), +so another reason is interoperability. + + +[heading Pointer to member object types] + +Despite their syntax, pointer to member object types can be seen as +dereferencing functionals. + + +[heading The ClassTransform template parameter] + +[^This]-pointer, [^this]-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. + +Special treatment of the class type within the sequence can significantly +complicate client code. A custom [^ClassTransform] argument allows the +client to adjust the class type before the sequence is formed and then +treat all parameters uniformly. + + +[heading Why tag types?] + +Let's consider the alternatives. + +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. + +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. + +[heading Is it safe to have the synthesis templates take a callable +builtin type or an MPL sequence as the first template argument?] + +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. + +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. + +[heading Why does the hidden [^this] parameter count for the +function arity of member functions?] + +It was found preferable that the following condition holds: + + mpl::size< __parameter_types >::value == __function_arity::value + +[heading Why ignore top-level cv-qualifiers on pointers?] + +A cv-qualified pointer is still a pointer. It usually doesn't matter and +even if it does, it's a job for +[@../../../type_traits/index.html Boost.TypeTraits]. + + +[endsect] + +[section:acknowledgements Acknowledgements] + +Thanks go to the following people for supporting the development of this +library in one or the other way: + +* David Abrahams +* Tom Brinkman +* Aleksey Gurtovoy +* Jody Hagins +* Hartmut Kaiser +* Andy Little +* John Maddock +* Paul Mensonides +* Alexander Nasonov +* Richard Smith +* Rob Stewart +* Jonathan Turkanis +* Pavel Vozenilek +* Steven Watanabe + +[endsect] + diff --git a/doc/html/boost_functiontypes/about_tag_types.html b/doc/html/boost_functiontypes/about_tag_types.html new file mode 100644 index 0000000..217b2ab --- /dev/null +++ b/doc/html/boost_functiontypes/about_tag_types.html @@ -0,0 +1,94 @@ + + + + About Tag Types + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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. +

+

+ These tags can be used to determine whether one property of a type has a particular + value. +

+
+is_function<int(...), variadic>::value // == true
+is_function<int()   , variadic>::value // == false
+
+

+ A compound property tag describes a combination of possible values of different + properties. The type components<F>, where F + is a callable builtin type, is a compound property tag that describes F. + The tag class template can be used to combine property tags. +

+
+tag<non_const,default_cc> // combination of two properties
+
+

+ When several values for the same property are specified in tag's + argument list, only the rightmost one is used; others are ignored. +

+
+tag<components<F>, default_cc> // overrides F's calling convention property
+
+

+ When compound property tag is specified to analyse a type, all of its component + properties must match. +

+
+is_member_function_pointer< F, tag<const_qualified,default_cc> >::value
+// true for 
+//   F = void(a_class::*)() const
+// false for
+//   F = void(a_class::*)()
+//   F = void(__fastcall a_class::*)() const
+
+

+ Default values are selected for properties not specified by the tag in the + context of type synthesis. +

+
+// given S = mpl::vector<int,a_class const &>
+
+member_function_pointer<S>::type // is int (a_class::*)() const
+// note: the cv-qualification is picked based on the class type,
+// a nonvariadic signature and the default calling convention 
+// are used
+
+member_function_pointer<S,non_const>::type // is int (a_class::*)()
+// no const qualification, as explicitly specified by the tag type
+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/acknowledgements.html b/doc/html/boost_functiontypes/acknowledgements.html new file mode 100644 index 0000000..e8c7c26 --- /dev/null +++ b/doc/html/boost_functiontypes/acknowledgements.html @@ -0,0 +1,85 @@ + + + + Acknowledgements + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHome +
+
+ +

+ Thanks go to the following people for supporting the development of this library + in one or the other way: +

+
    +
  • + David Abrahams +
  • +
  • + Tom Brinkman +
  • +
  • + Aleksey Gurtovoy +
  • +
  • + Jody Hagins +
  • +
  • + Hartmut Kaiser +
  • +
  • + Andy Little +
  • +
  • + John Maddock +
  • +
  • + Paul Mensonides +
  • +
  • + Alexander Nasonov +
  • +
  • + Richard Smith +
  • +
  • + Rob Stewart +
  • +
  • + Jonathan Turkanis +
  • +
  • + Pavel Vozenilek +
  • +
  • + Steven Watanabe +
  • +
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHome +
+ + diff --git a/doc/html/boost_functiontypes/introduction.html b/doc/html/boost_functiontypes/introduction.html new file mode 100644 index 0000000..58151d4 --- /dev/null +++ b/doc/html/boost_functiontypes/introduction.html @@ -0,0 +1,94 @@ + + + + Introduction + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ Boost.FunctionTypes provides functionality to classify, decompose and synthesize + function, function pointer, function reference and pointer to member types. +

+

+ We collectively refer to these types as callable builtin + types. +

+

+ In particular, the library can be used to: +

+
    +
  • + test whether a type is a specific callable, builtin type, +
  • +
  • + extract all component properties from callable, builtin types, and +
  • +
  • + create callable, builtin types from specified properties. +
  • +
+

+ The library is designed to work well with other Boost libraries and uses well-accepted + concepts introduced by Boost and TR1. +

+

+ Templates that encapsulate boolean or numeric properties define a static member + constant called value. +

+
+is_function_pointer< bool(*)(int) >::value // == true 
+
+function_arity< bool(*)(int) >::value // == 1
+
+

+ Templates that encapsulate properties that are single types contain a type + member called type. +

+
+function_type< mpl::vector<bool,int> >::type // is bool(int)
+
+result_type< bool(&)(int) >::type // is bool
+
+

+ Templates that encapsulate properties that are type lists model an MPL-compatible + type sequence. +

+
+parameter_types< bool(int) > // models an MPL sequence
+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/rationale.html b/doc/html/boost_functiontypes/rationale.html new file mode 100644 index 0000000..1b71df4 --- /dev/null +++ b/doc/html/boost_functiontypes/rationale.html @@ -0,0 +1,149 @@ + + + + Rationale + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ + Error + handling rationale +

+

+ 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. +

+

+ The library's components have limited error conditions, so problematic input + can be spotted easily. +

+

+ + Why MPL Sequences? +

+

+ 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 boost::function + after applying boost::bind) + can be expressed more easily. The MPL Sequence concept is compatible with several + other Boost libraries (most importantly Fusion), + so another reason is interoperability. +

+

+ + Pointer + to member object types +

+

+ Despite their syntax, pointer to member object types can be seen as dereferencing + functionals. +

+

+ + The + ClassTransform template parameter +

+

+ This-pointer, this-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. +

+

+ Special treatment of the class type within the sequence can significantly complicate + client code. A custom ClassTransform argument allows the + client to adjust the class type before the sequence is formed and then treat + all parameters uniformly. +

+

+ + Why tag types? +

+

+ Let's consider the alternatives. +

+

+ 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. +

+

+ 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. +

+

+ + Is + it safe to have the synthesis templates take a callable builtin type or an + MPL sequence as the first template argument? +

+

+ 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. +

+

+ 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. +

+

+ + Why + does the hidden this parameter count for the function arity + of member functions? +

+

+ It was found preferable that the following condition holds: +

+
+mpl::size< parameter_types<T> >::value == function_arity<T>::value
+
+

+ + Why + ignore top-level cv-qualifiers on pointers? +

+

+ A cv-qualified pointer is still a pointer. It usually doesn't matter and even + if it does, it's a job for Boost.TypeTraits. +

+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/reference.html b/doc/html/boost_functiontypes/reference.html new file mode 100644 index 0000000..f54c521 --- /dev/null +++ b/doc/html/boost_functiontypes/reference.html @@ -0,0 +1,49 @@ + + + + Reference + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+ + + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/reference/classification.html b/doc/html/boost_functiontypes/reference/classification.html new file mode 100644 index 0000000..7ef1d9e --- /dev/null +++ b/doc/html/boost_functiontypes/reference/classification.html @@ -0,0 +1,407 @@ + + + + Class + templates for type classification + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+template<typename T, typename Tag = null_tag>
+struct is_function;
+
+

+ Header +

+
+#include <boost/function_types/is_function.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_function<T,Tag>
+

+ Predicate value as MPL + - Integral + Constant +

+
is_function<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a function, possibly with additional + properties as specified by a property tag. +

+
+
+ +
+template<typename T, typename Tag = null_tag>
+struct is_function_pointer;
+
+

+ Header +

+
+#include <boost/function_types/is_function_pointer.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_function_pointer<T,Tag>
+

+ Predicate value MPL - + Integral + Constant +

+
is_function_pointer<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a function pointer, possibly with additional + properties as specified by a property tag. +

+
+
+ +
+template<typename T, typename Tag = null_tag>
+struct is_function_reference;
+
+

+ Header +

+
+#include <boost/function_types/is_function_reference.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_function_reference<T,Tag>
+

+ Predicate value MPL - + Integral + Constant +

+
is_function_reference<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a function reference, possibly with + additional properties as specified by a property tag. +

+
+
+ +
+template<typename T, typename Tag = null_tag>
+struct is_member_pointer;
+
+

+ Header +

+
+#include <boost/function_types/is_member_pointer.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_member_pointer<T,Tag>
+

+ Predicate value MPL - + Integral + Constant +

+
is_member_pointer<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a pointer to member (object or function) + type, possibly with additional properties as specified by a property tag. +

+
+
+ +
+template<typename T>
+struct is_member_object_pointer;
+
+

+ Header +

+
+#include <boost/function_types/is_member_object_pointer.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
is_member_object_pointer<T>
+

+ Predicate value MPL - + Integral + Constant +

+
is_member_object_pointer<T>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a pointer to member object type. +

+
+
+ +
+template<typename T, typename Tag = null_tag>
+struct is_member_function_pointer;
+
+

+ Header +

+
+#include <boost/function_types/is_member_function_pointer.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_member_function_pointer<T,Tag>
+

+ Predicate value MPL - + Integral + Constant +

+
is_member_function_pointer<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a member function pointer, possibly + with additional properties as specified by a property tag. +

+
+
+ +
+template<typename T, typename Tag = null_tag>
+struct is_callable_builtin;
+
+

+ Header +

+
+#include <boost/function_types/is_callable_builtin.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_callable_builtin<T,Tag>
+

+ Predicate value as MPL + - Integral + Constant +

+
is_callable_builtin<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ Determines whether a given type is a callable builtin, possibly with additional + properties as specified by a property tag. +

+
+
+ +
+template<typename T, typename Tag = null_tag>
+struct is_nonmember_callable_builtin;
+
+

+ Header +

+
+#include <boost/function_types/is_nonmember_callable_builtin.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
Tag
+

+ Further properties required for a positive result +

+
is_nonmember_callable_builtin<T,Tag>
+

+ Predicate value as MPL + - Integral + Constant +

+
is_nonmember_callable_builtin<T,Tag>::value
+

+ Constant boolean value +

+
+
+

+ 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. +

+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/reference/decomposition.html b/doc/html/boost_functiontypes/reference/decomposition.html new file mode 100644 index 0000000..91ebf50 --- /dev/null +++ b/doc/html/boost_functiontypes/reference/decomposition.html @@ -0,0 +1,233 @@ + + + + Class templates + for type decomposition + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+template<typename F>
+struct result_type;
+
+

+ Header +

+
+#include <boost/function_types/result_type.hpp>
+
+
+

+
+
F
+

+ Type to analyze +

+
result_type<F>::type
+

+ Result type of F +

+
+
+

+ Extracts the result type of a callable, builtin type. +

+

+ If F is no callable, builtin type, any attempt to access + the type member results in a compile error. +

+
+
+ +
+template<typename F, class ClassTransform = add_reference<_> >
+struct parameter_types;
+
+

+ Header +

+
+#include <boost/function_types/parameter_types.hpp>
+
+
+

+
+
F
+

+ Type to analyze +

+
ClassTransform
+

+ MPL - Lambda + Expression to transform the class type if F + is a member function pointer +

+
parameter_types<F,ClassTransform>
+

+ MPL - Front + / Back + Extensible + Random + Access Sequence of parameter types +

+
+
+

+ Extracts the parameter types of a callable, builtin type. +

+

+ If F is no callable, builtin type, any attempt to access + the sequence results in a compile error. +

+
+
+ +
+template<typename F>
+struct function_arity;
+
+

+ Header +

+
+#include <boost/function_types/function_arity.hpp>
+
+
+

+
+
F
+

+ Callable builtin type +

+
function_arity<F>
+

+ Function arity as MPL + - Integral + Constant +

+
function_arity<F>::value
+

+ Constant value of the function arity +

+
+
+

+ Extracts the function arity, that is the number of parameters. The hidden + this of member function pointers counts, in other words + the arity value is always greater than or equal to one if F + is a member function pointer. +

+

+ If F is no callable, builtin type, any attempt to access + the value results in a compile error. +

+
+
+ +
+template<typename T, class ClassTransform = add_reference<_> >
+struct components;
+
+

+ Header +

+
+#include <boost/function_types/components.hpp>
+
+
+

+
+
T
+

+ Type to analyze +

+
ClassTransform
+

+ MPL - Lambda + Expression to transform the class type if T + is a member function pointer +

+
components<T,ClassTransform>
+

+ MPL - Front + / Back + Extensible + Random + Access Sequence of all component types and property tag +

+
components<T,ClassTransform>::types
+

+ Decorated MPL Sequence, exposed for optimization +

+
+
+

+ Extracts all properties of a callable builtin type, that is the result + type, followed by the parameter types (including the type of this + for member function pointers). +

+

+ If T is no callable builtin type, the component types + are an empty sequence and the Tag's meaning is equivalent to the null_tag. +

+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/reference/macros.html b/doc/html/boost_functiontypes/reference/macros.html new file mode 100644 index 0000000..24c18db --- /dev/null +++ b/doc/html/boost_functiontypes/reference/macros.html @@ -0,0 +1,246 @@ + + + + Macros + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +

+ Expands to a numeric value that describes the maximum function arity supported + by the library. +

+

+ Defaults to 20 if not explicitly defined by the user before inclusion of + the first library header. +

+
+

+ 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 boost/function_types/config/compiler.hpp. +

+
+ +

+ Expands to a sequence + of ternary tuples + (these data types are defined in the documentation + of the Boost Preprocessor library). Each sequence element describes + one calling convention specifier. The first element in each tuple is the + macro suffix for BOOST_FT_CC_*, + 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 BOOST_PP_EMPTY + or BOOST_PP_IDENTITY(name). +

+

+ Define this macro to extend the set of possible names for custom calling + conventions. The macro expands to nothing by default. +

+

+ The following names are predefined by the library and must not occur in + the definition of BOOST_FT_CC_NAMES: +

+
+#define BOOST_FT_BUILTIN_CC_NAMES \
+  (( IMPLICIT           , implicit_cc , BOOST_PP_EMPTY                ))\
+  (( CDECL              , cdecl_cc    , BOOST_PP_IDENTITY(__cdecl   ) ))\
+  (( STDCALL            , stdcall_cc  , BOOST_PP_IDENTITY(__stdcall ) ))\
+  (( PASCAL             , pascal_cc   , BOOST_PP_IDENTITY(pascal    ) ))\
+  (( FASTCALL           , fastcall_cc , BOOST_PP_IDENTITY(__fastcall) ))\
+  (( CLRCALL            , clrcall_cc  , BOOST_PP_IDENTITY(__clrcall ) ))\
+  (( THISCALL           , thiscall_cc , BOOST_PP_IDENTITY(__thiscall) ))\
+  (( IMPLICIT_THISCALL  , thiscall_cc , BOOST_PP_EMPTY                )) 
+// Don't get confused by the last line, here (thiscall can't be specified
+// explicitly prior to MSVC 8).
+
+
+
+ +

+ Enables a specific calling convention. * dentoes the macro suffix, as defined + by BOOST_FT_CC_NAMES + or BOOST_FT_BUILTIN_CC_NAMES. +

+

+ The macro expands to a list of restrictions, separated by the | + character. Possible items are: +

+
    +
  • + callable_builtin +
  • +
  • + member +
  • +
  • + non_member +
  • +
  • + variadic +
  • +
  • + non_variadic +
  • +
+

+ If no such macro is defined for a particular calling convention, it is + disabled. Example: +

+
+#define BOOST_FT_CC_STDCALL non_variadic|callable_builtin
+// enables stdcall calling convention for all non-variadic, 
+// callable, builtin types
+
+
+
+ +

+ Defining this macro causes the following macros to be defined, if not defined + already: +

+
+#define BOOST_FT_CC_CDECL BOOST_FT_COMMON_X86_CCs
+#define BOOST_FT_CC_STDCALL non_variadic|BOOST_FT_COMMON_X86_CCs
+#define BOOST_FT_CC_FASTCALL non_variadic|BOOST_FT_COMMON_X86_CCs
+
+
+
+ +

+ 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. +

+

+ The default definition is as follows: +

+
+#define BOOST_FT_SYNTAX(result,lparen,cc_spec,type_mod,name,rparen) \
+          result() lparen() cc_spec() type_mod() name() rparen()
+
+
+
+ +

+ Set to void for compilers that insist on a void + parameter for nullary function types, empty by default. +

+
+
+ +

+ 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 1 until + the standard changes, setting this macro to 0 may not + work. +

+
+

+ The following macros are useful for testing when changing + the source code of the library. +

+
+ +

+ Makes the compiler preprocess as much as possible of the library code (rather + than loading already-preprocessed header files) if defined. +

+
+
+ +

+ Makes the compiler preprocess the loop over possible names for custom calling + conventions (rather than loading an already-preprocessed header file) if + defined. +

+

+ This macro is defined automatically if BOOST_FT_CC_NAMES + has been defined. +

+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/reference/synthesis.html b/doc/html/boost_functiontypes/reference/synthesis.html new file mode 100644 index 0000000..367db36 --- /dev/null +++ b/doc/html/boost_functiontypes/reference/synthesis.html @@ -0,0 +1,230 @@ + + + + Class templates + for type synthesis + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+template<typename Types, typename Tag = null_tag> 
+struct function_type;
+
+

+ Header +

+
+#include <boost/function_types/function_type.hpp>
+
+
+

+
+
Types
+

+ Component types in form of an MPL + - Forward + Sequence or another callable, builtin type +

+
Tag
+

+ Further properties +

+
function_type<Types,Tag>::type
+

+ Synthesized type +

+
+
+

+ Synthesizes a function type from given properties. +

+

+ If the template parameters do not describe a valid type, any attempt to + access the type member will result in a compile error. +

+
+
+ +
+template<typename Types, typename Tag = null_tag> 
+struct function_pointer;
+
+

+ Header +

+
+#include <boost/function_types/function_pointer.hpp>
+
+
+

+
+
Types
+

+ Component types in form of an MPL + - Forward + Sequence or another callable, builtin type +

+
Tag
+

+ Further properties +

+
function_pointer<Types,Tag>::type
+

+ Synthesized type +

+
+
+

+ Synthesizes a function pointer type from given properties. +

+

+ If the template parameters do not describe a valid type, any attempt to + access the type member will result in a compile error. +

+
+
+ +
+template<typename Types, typename Tag = null_tag> 
+struct function_reference;
+
+

+ Header +

+
+#include <boost/function_types/function_reference.hpp>
+
+
+

+
+
Types
+

+ Component types in form of an MPL + - Forward + Sequence or another callable, builtin type +

+
Tag
+

+ Further properties +

+
function_reference<Types,Tag>::type
+

+ Synthesized type +

+
+
+

+ Synthesizes a function reference type from given properties. +

+

+ If the template parameters do not describe a valid type, any attempt to + access the type member will result in a compile error. +

+
+
+ +
+template<typename Types, typename Tag = null_tag> 
+struct member_function_pointer;
+
+

+ Header +

+
+#include <boost/function_types/member_function_pointer.hpp>
+
+
+

+
+
Types
+

+ Component types in form of an MPL + - Forward + Sequence or another callable, builtin type +

+
Tag
+

+ Further properties +

+
member_function_pointer<Types,Tag>::type
+

+ Synthesized type +

+
+
+

+ Synthesizes a member function pointer type from given properties. +

+

+ 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. +

+

+ If the template parameters do not describe a valid type, any attempt to + access the type member will result in a compile error. +

+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/reference/tag_types.html b/doc/html/boost_functiontypes/reference/tag_types.html new file mode 100644 index 0000000..eb40aac --- /dev/null +++ b/doc/html/boost_functiontypes/reference/tag_types.html @@ -0,0 +1,320 @@ + + + + Tag Types + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ + +
+ +
+typedef unspecified variadic;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type takes a variable number of arguments through + an ellipsis parameter (such as printf). +

+
+
+ +
+typedef unspecified non_variadic;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type does not have an ellipsis parameter. +

+
+
+ +
+typedef unspecified default_cc;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type encodes the default calling convention. +

+
+
+ +
+typedef unspecified const_qualified;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is const qualified. +

+
+
+ +
+typedef unspecified non_const;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is not const qualified. +

+
+
+ +
+typedef unspecified volatile_qualified;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is volatile qualified. +

+
+
+ +
+typedef unspecified non_volatile;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is not volatile qualified. +

+
+
+ +
+typedef unspecified non_cv;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is neither const nor volatile qualified. Equivalent + to __tag<__non_const,__non_volatile>, + but involves fewer template instantiations when evaluated. +

+
+
+ +
+typedef unspecified const_non_volatile;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is const but not volatile qualified. Equivalent + to __tag<__const_qualified,__non_volatile>, + but involves fewer template instantiations when evaluated. +

+
+
+ +
+typedef unspecified volatile_non_const;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is volatile but not const qualified. Equivalent + to __tag<__volatile_qualified,__non_const>, + but involves fewer template instantiations when evaluated. +

+
+
+ +
+typedef unspecified cv_qualified;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States that a function type is both const and volatile qualified. Equivalent + to __tag<__const_qualified,__volatile_qualified>, + but involves fewer template instantiations when evaluated. +

+
+
+ +
+typedef unspecified null_tag;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+

+ States nothing. +

+
+
+ +
+template<class Tag1, class Tag2, 
+    class Tag3 = null_tag, class Tag4 = null_tag>
+struct tag;
+
+

+ Header +

+
+#include <boost/function_types/property_tags.hpp>
+
+
+

+
+
TagN
+

+ Property tag +

+
tag<Tag1,Tag2...>
+

+ Compound property tag +

+
+
+

+ 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. +

+
+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boost_functiontypes/use_cases.html b/doc/html/boost_functiontypes/use_cases.html new file mode 100644 index 0000000..ab9e332 --- /dev/null +++ b/doc/html/boost_functiontypes/use_cases.html @@ -0,0 +1,175 @@ + + + + Use Cases + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ 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 const/volatile-qualifiers, + a function may take a variable number of (additional, POD-typed) arguments + (such as printf) and several C++ implementations encode + a calling convention with each function's type to allow calls across language + or (sub-)system boundaries. +

+
+template<typename R>
+void accept_function(R(* func)());
+
+template<typename R>
+void accept_function(R(& func)());
+
+template<typename R, typename C>
+void accept_function(R(C::* func)());
+
+template<typename R, typename C>
+void accept_function(R(C::* func)() const);
+
+template<typename R, typename C>
+void accept_function(R(C::* func)() volatile);
+
+template<typename R, typename C>
+void accept_function(R(C::* func)() const volatile);
+
+template<typename R>
+void accept_function(R(* func)(...));
+
+template<typename R>
+void accept_function(R(& func)(...));
+
+template<typename R, typename C>
+void accept_function(R(C::* func)(...));
+
+template<typename R, typename C>
+void accept_function(R(C::* func)(...) const);
+
+template<typename R, typename C>
+void accept_function(R(C::* func)(...) volatile);
+
+template<typename R, typename C>
+void accept_function(R(C::* func)(...) const volatile);
+
+// ...
+
+// needs to be repeated for every additional function parameter
+// times the number of possible calling conventions
+
+

+ 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. +

+

+ Using Boost.FunctionTypes it is possible to write a single function template + instead: +

+
+template<typename F>
+void accept_function(F f)
+{
+  // ... use Boost.FunctionTypes to analyse F
+}
+
+

+ The combination with a tuples library that provides an invoker component, such + as Boost.Fusion, allows to + build flexible callback facilities that are entirely free of repetitive code + as shown by the interpreter + example. +

+

+ 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 float(float) + overload of std::abs. +

+
+float (*ptr_absf)(float) = & std::abs;
+
+
+void foo(float(*func)(float));
+
+void bar() 
+{ 
+  foo(& std::abs); 
+}
+
+
+std::transform(b, e, o, static_cast<float(*)(float)>(& std::abs));
+
+

+ The library's type synthesis capabilities can be used to automate overload + selection and instantiation of function templates. Given an overloaded function + template +

+
+template<typename R, typename T0>
+R overloaded(T0);
+
+template<typename R, typename T0, typename T1>
+R overloaded(T0,T1);
+
+template<typename R. typename T0, typename T1, typename T2>
+R overloaded(T0,T1,T2);
+
+

+ we can pick any of the three overloads and instantiate the template with template + arguments from a type sequence in a single expression: +

+
+static_cast<function_pointer<Seq>::type>(& overloaded)
+
+

+ 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 interface + example. +

+

+ 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 + fast_mem_fn example + exploits this characteristic and implements a potentially inlining version + of boost::mem_fn limited to + member functions that are known at compile time. +

+
+ + + +
Copyright © 2004 -2007 Tobias Schwinger
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/boostbook.css b/doc/html/boostbook.css new file mode 100644 index 0000000..858d43c --- /dev/null +++ b/doc/html/boostbook.css @@ -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; + } + } diff --git a/doc/html/index.html b/doc/html/index.html new file mode 100644 index 0000000..358b001 --- /dev/null +++ b/doc/html/index.html @@ -0,0 +1,55 @@ + + + +Chapter 1. Boost.FunctionTypes 2.5 + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
Next
+
+
+

+Chapter 1. Boost.FunctionTypes 2.5

+

+Tobias Schwinger +

+
+
+

+ Distributed under 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) +

+
+
+ +
+ + + +

Last revised: May 13, 2007 at 13:12:48 GMT

+
+
Next
+ + diff --git a/example/Jamfile b/example/Jamfile new file mode 100644 index 0000000..08ab43d --- /dev/null +++ b/example/Jamfile @@ -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 + : . ; # needed for Boost.PP file iteration with some compilers + +exe macro_type_args_example : macro_type_args_example.cpp ; + + diff --git a/example/detail/param_type.hpp b/example/detail/param_type.hpp new file mode 100644 index 0000000..7c0fd5f --- /dev/null +++ b/example/detail/param_type.hpp @@ -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 + +#include +#include + +#include +#include + +#include +// #include + +// namespace boost +namespace example +{ + namespace mpl = boost::mpl; + + // namespace utility + // { + namespace param_type_detail + { + template + struct by_ref_cond + { + typedef by_ref_cond type; + BOOST_STATIC_CONSTANT(bool,value = sizeof(void*) < sizeof(T)); + }; + + template + struct add_ref_to_const + : boost::add_reference< typename boost::add_const::type > + { }; + } + + template + struct param_type + : mpl::eval_if< param_type_detail::by_ref_cond + , param_type_detail::add_ref_to_const, mpl::identity > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,param_type,(T)) + }; + // } + // BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,utility::param_type) +} + +#endif + diff --git a/example/fast_mem_fn.hpp b/example/fast_mem_fn.hpp new file mode 100644 index 0000000..97f95b0 --- /dev/null +++ b/example/fast_mem_fn.hpp @@ -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 +#include +#include +#include + +#include +#include +#include +#include + +#include + +#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::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() + + template + struct fast_mem_fn_maker + { + template + fast_mem_fn make_fast_mem_fn() + { + return fast_mem_fn(); + } + }; + + template + typename boost::enable_if, + fast_mem_fn_maker >::type + make_fast_mem_fn(MFPT) + { + return fast_mem_fn_maker(); + } + + + // ------- ---- --- -- - - - - + + namespace detail + { + // by-value forwarding optimization + template + struct parameter_types + : mpl::transform_view,param_type<_> > + { }; + } + + // ------- ---- --- -- - - - - + + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type::type result_type; + typedef detail::parameter_types parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin::type i0; + public: + // forwarding function call operator + result_type operator()( typename mpl::deref::type a0) const + { + return (a0.*MemberFunction)(); + }; + }; + + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type::type result_type; + typedef detail::parameter_types parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin::type i0; + typedef typename mpl::next::type i1; + public: + // forwarding function call operator + result_type operator()( typename mpl::deref::type a0 + , typename mpl::deref::type a1) const + { + return (a0.*MemberFunction)(a1); + }; + }; + + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type::type result_type; + typedef detail::parameter_types parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin::type i0; + typedef typename mpl::next::type i1; + typedef typename mpl::next::type i2; + public: + // forwarding function call operator + result_type operator()( typename mpl::deref::type a0 + , typename mpl::deref::type a1 + , typename mpl::deref::type a2) const + { + return (a0.*MemberFunction)(a1,a2); + }; + }; + + // ... +} + +// ------- ---- --- -- - - - - + +// preprocessor-based code generator to continue the repetitive part, above + +#include +#include +#include +#include +#include +#include + +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 + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type::type result_type; + typedef detail::parameter_types parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin::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::type a) ) const + { + return (a0.*MemberFunction)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,a)); + }; + }; + #undef N + +#endif +#endif + diff --git a/example/fast_mem_fn_example.cpp b/example/fast_mem_fn_example.cpp new file mode 100644 index 0000000..efe66a1 --- /dev/null +++ b/example/fast_mem_fn_example.cpp @@ -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 +#include +#include +#include +#include + +#include +#include + +#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 +class test_compare +{ + CriterionExtractor fnc_criterion; + Comparator fnc_compare; +public: + + explicit test_compare(CriterionExtractor criterion, Comparator compare) + : fnc_criterion(criterion) + , fnc_compare(compare) + { } + + template + 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 +test_compare +make_test_compare(CriterionExtractor criterion, Comparator compare) +{ + return test_compare(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_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 void do_test(test_vector & v, F criterion) +{ + std::sort(v.begin(),v.end(),make_test_compare(criterion,std::greater())); + 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; +} + diff --git a/example/interface.hpp b/example/interface.hpp new file mode 100644 index 0000000..cadf740 --- /dev/null +++ b/example/interface.hpp @@ -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 + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + struct concat_view + : mpl::joint_view, Seq> + { }; + + // metafunction returning a function pointer type for a vtable entry + template + struct vtable_entry + : ft::function_pointer + < concat_view< typename Inf::result, mpl::transform_view< + typename Inf::params, param_type<_> > > > + { }; + + // the expression '& member::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 + struct member + { + typedef typename ft::member_function_pointer + < concat_view,Tag + >::type + mem_func_ptr; + + typedef typename mpl::at_c::type context; + + template + static typename Inf::result wrap(void* c) + { + return (reinterpret_cast(c)->*MemFuncPtr)(); + } + template + static typename Inf::result wrap(void* c, T0 a0) + { + return (reinterpret_cast(c)->*MemFuncPtr)(a0); + } + template + static typename Inf::result wrap(void* c, T0 a0, T1 a1) + { + return (reinterpret_cast(c)->*MemFuncPtr)(a0,a1); + } + // continue with the preprocessor (the scheme should be clear, by now) + #define BOOST_PP_LOCAL_MACRO(n) \ + template \ + static typename Inf::result wrap(void* c, \ + BOOST_PP_ENUM_BINARY_PARAMS(n,T,a)) \ + { \ + return (reinterpret_cast(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 + 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 struct vtable_holder \ + { \ + static vtable const val_vtable; \ + }; \ + \ + public: \ + \ + template \ + inline name (T & that) \ + : ptr_vtable(& vtable_holder::val_vtable) \ + , ptr_that(boost::addressof(that)) \ + { } \ + \ + BOOST_EXAMPLE_INTERFACE__MEMBERS(def,FUNCTION) \ + }; \ + \ + template \ + name ::vtable const name ::vtable_holder::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 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 >::type func0; + + // second function + template struct inf1 + { + typedef int result; + typedef ::boost::mpl::vector< T > params; + }; + ::example::vtable_entry >::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 struct vtable_holder + { + static vtable const val_vtable; + }; + +public: + + // converting ctor, creates an interface from an arbitrary class + template + inline interface_x (T & that) + : ptr_vtable(& vtable_holder::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,1>::type p0) const + { + return ptr_vtable-> func0(ptr_that , p0); + } + + inline vtable::inf1<> ::result another_func () + { + return ptr_vtable-> func1(ptr_that ); + } +}; + +template +interface_x ::vtable const interface_x ::vtable_holder::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, ::example::ft:: const_qualified > + ::template wrap < &T:: a_func > +, & ::example::member< vtable::inf1, ::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 \ + struct BOOST_PP_CAT(inf,i) \ + { \ + typedef result_type result; \ + typedef ::boost::mpl::vector< BOOST_PP_SEQ_ENUM(param_types) > params; \ + }; \ + ::example::vtable_entry >::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), \ + ::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::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 + + diff --git a/example/interface_example.cpp b/example/interface_example.cpp new file mode 100644 index 0000000..d4f66bb --- /dev/null +++ b/example/interface_example.cpp @@ -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 + +#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 + 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(); +} + diff --git a/example/interpreter.hpp b/example/interpreter.hpp new file mode 100644 index 0000000..9e75bf7 --- /dev/null +++ b/example/interpreter.hpp @@ -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 +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +namespace example +{ + namespace fusion = boost::fusion; + namespace ft = boost::function_types; + namespace mpl = boost::mpl; + + class interpreter + { + class token_parser; + typedef boost::function invoker_function; + typedef std::map dictionary; + + dictionary map_invokers; + public: + // Registers a function with the interpreter. + template + typename boost::enable_if< ft::is_nonmember_callable_builtin + >::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 >::type + , class To = typename mpl::end< ft::parameter_types >::type + > + struct invoker; + }; + + class interpreter::token_parser + { + typedef boost::token_iterator_generator< + boost::char_separator >::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 + struct remove_cv_ref + : boost::remove_cv< typename boost::remove_reference::type > + { }; + public: + // Returns a token of given type. + // We just apply boost::lexical_cast to whitespace separated string tokens + // for simplicity. + template + typename remove_cv_ref::type get() + { + if (! this->has_more_tokens()) + throw std::runtime_error("unexpected end of input"); + + try + { + typedef typename remove_cv_ref::type result_type; + result_type result = boost::lexical_cast + ::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 + struct interpreter::invoker + { + // add an argument to a Fusion cons-list for each parameter type + template + static inline + void apply(Function func, token_parser & parser, Args const & args) + { + typedef typename mpl::deref::type arg_type; + + invoker::type, To>::apply + ( func, parser, fusion::push_back(args, parser.get()) ); + } + }; + + template + struct interpreter::invoker + { + // the argument list is complete, now call the function + template + static inline + void apply(Function func, token_parser &, Args const & args) + { + fusion::invoke(func,args); + } + }; + + template + typename boost::enable_if< ft::is_nonmember_callable_builtin >::type + interpreter::register_function(std::string const & name, Function f) + { + // instantiate and store the invoker by name + this->map_invokers[name] = boost::bind( + & invoker::template apply, f,_1,fusion::nil() ); + } + + + void interpreter::parse_input(std::string const & text) const + { + boost::char_separator s(" \t\n\r"); + + token_parser parser + ( boost::make_token_iterator(text.begin(), text.end(), s) + , boost::make_token_iterator(text.end() , text.end(), s) ); + + while (parser.has_more_tokens()) + { + // read function name + std::string func_name = parser.get(); + + // 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); + } + } + +} + diff --git a/example/interpreter_example.cpp b/example/interpreter_example.cpp new file mode 100644 index 0000000..9e6118b --- /dev/null +++ b/example/interpreter_example.cpp @@ -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 +#include +#include + +#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; +} + diff --git a/example/macro_type_args.hpp b/example/macro_type_args.hpp new file mode 100644 index 0000000..3500524 --- /dev/null +++ b/example/macro_type_args.hpp @@ -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) // ERROR (wrong number of macro arguments) +// +// This problem can be solved by pasing using a parenthesized type +// +// MY_MACRO((std::map) // 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 >::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 +#include + +#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 + diff --git a/example/macro_type_args_example.cpp b/example/macro_type_args_example.cpp new file mode 100644 index 0000000..9f83883 --- /dev/null +++ b/example/macro_type_args_example.cpp @@ -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 +#include +#include + +#include +#include + +#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 + struct mpl_seq_to_string_impl + { + static std::string get(std::string const & prev) + { + typedef typename mpl::next::type next_pos; + typedef typename mpl::deref::type type; + + return mpl_seq_to_string_impl::get( + prev + (prev.empty()? '\0' : ',') + typeid(type).name() ); + } + }; + template + struct mpl_seq_to_string_impl + { + static std::string get(std::string const & prev) + { + return prev; + } + }; + + template + std::string mpl_seq_to_string() + { + typedef typename mpl::begin::type begin; + typedef typename mpl::end::type end; + + return mpl_seq_to_string_impl::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; + +} + diff --git a/example/result_of.hpp b/example/result_of.hpp new file mode 100644 index 0000000..1527221 --- /dev/null +++ b/example/result_of.hpp @@ -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 +#include + +#include +#include + +namespace example +{ + namespace ft = boost::function_types; + namespace mpl = boost::mpl; + + template struct result_of; + + namespace detail + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) + + template + struct result_type_member + { + typedef typename F::result_type type; + }; + + template + struct result_member_template + { + typedef typename F::template result::type type; + }; + +#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564)) + template + struct result_member_template< F, F(void) > + { + typedef void type; + }; +#endif + + template + struct result_of_impl + : mpl::eval_if + < ft::is_callable_builtin + , ft::result_type + , mpl::eval_if + < has_result_type + , result_type_member + , result_member_template + > > + { }; + } + + template + struct result_of + : detail::result_of_impl< typename ft::result_type::type, Desc > + { }; +} + diff --git a/example/result_of_example.cpp b/example/result_of_example.cpp new file mode 100644 index 0000000..a8fe2d2 --- /dev/null +++ b/example/result_of_example.cpp @@ -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 +#include +#include + +struct int_result_type { typedef int result_type; }; + +struct int_result_of +{ + template struct result { typedef int type; }; +}; + +struct int_result_type_and_float_result_of +{ + typedef int result_type; + template 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::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, void>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + BOOST_STATIC_ASSERT((is_same::type, int>::value)); + return 0; +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..ee4ce6e --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + +

Automatic redirection failed, please go to + doc/html/index.html.

+

Copyright Tobias Schwinger 2005-2007

+

Distributed under the Boost Software License, Version 1.0. (See accompanying file + LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt).

+ + + diff --git a/test/Jamfile b/test/Jamfile new file mode 100644 index 0000000..34658ee --- /dev/null +++ b/test/Jamfile @@ -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 + : ../example + ] + [ compile ../example/macro_type_args_example.cpp ] + ; +} + + diff --git a/test/classification/is_callable_builtin.cpp b/test/classification/is_callable_builtin.cpp new file mode 100644 index 0000000..d65f6f3 --- /dev/null +++ b/test/classification/is_callable_builtin.cpp @@ -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 +#include + +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] > +)); + diff --git a/test/classification/is_cv_function.cpp b/test/classification/is_cv_function.cpp new file mode 100644 index 0000000..176300c --- /dev/null +++ b/test/classification/is_cv_function.cpp @@ -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 +#include + +namespace ft = boost::function_types; + +template +void test_non_cv(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function > + )); +} + +template +void test_c_non_v(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function > + )); +} + +template +void test_v_non_c(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function > + )); +} + +template +void test_cv(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function + )); + + BOOST_MPL_ASSERT(( + ft::is_function > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function > + )); +} + + +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); +} + diff --git a/test/classification/is_cv_mem_func_ptr.cpp b/test/classification/is_cv_mem_func_ptr.cpp new file mode 100644 index 0000000..0b75c43 --- /dev/null +++ b/test/classification/is_cv_mem_func_ptr.cpp @@ -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 +#include + +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 > +)); + +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 > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, + ft::tag > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, + ft::tag > +)); + +// + +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 > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< c_mem_func_ptr, + ft::tag > +)); + +// + +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 > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< v_mem_func_ptr, + ft::tag > +)); + +// + +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 > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag > +)); + diff --git a/test/classification/is_cv_pointer.cpp b/test/classification/is_cv_pointer.cpp new file mode 100644 index 0000000..383052e --- /dev/null +++ b/test/classification/is_cv_pointer.cpp @@ -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 +#include +#include + +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 > +)); + + diff --git a/test/classification/is_function.cpp b/test/classification/is_function.cpp new file mode 100644 index 0000000..9c6a357 --- /dev/null +++ b/test/classification/is_function.cpp @@ -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 +#include + +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] > +)); + diff --git a/test/classification/is_function_pointer.cpp b/test/classification/is_function_pointer.cpp new file mode 100644 index 0000000..54ef29f --- /dev/null +++ b/test/classification/is_function_pointer.cpp @@ -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 +#include + +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] > +)); + diff --git a/test/classification/is_function_reference.cpp b/test/classification/is_function_reference.cpp new file mode 100644 index 0000000..2f8f006 --- /dev/null +++ b/test/classification/is_function_reference.cpp @@ -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 +#include + +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] > +)); + + diff --git a/test/classification/is_member_function_pointer.cpp b/test/classification/is_member_function_pointer.cpp new file mode 100644 index 0000000..0548c37 --- /dev/null +++ b/test/classification/is_member_function_pointer.cpp @@ -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 +#include + +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] > +)); + diff --git a/test/classification/is_member_object_pointer.cpp b/test/classification/is_member_object_pointer.cpp new file mode 100644 index 0000000..8408327 --- /dev/null +++ b/test/classification/is_member_object_pointer.cpp @@ -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 +#include + +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] > +)); + diff --git a/test/classification/is_member_pointer.cpp b/test/classification/is_member_pointer.cpp new file mode 100644 index 0000000..1139027 --- /dev/null +++ b/test/classification/is_member_pointer.cpp @@ -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 +#include + +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& > +)); + diff --git a/test/classification/is_nonmember_callable_builtin.cpp b/test/classification/is_nonmember_callable_builtin.cpp new file mode 100644 index 0000000..902d6ee --- /dev/null +++ b/test/classification/is_nonmember_callable_builtin.cpp @@ -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 +#include + +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] > +)); + diff --git a/test/classification/is_variadic.cpp b/test/classification/is_variadic.cpp new file mode 100644 index 0000000..964ea8c --- /dev/null +++ b/test/classification/is_variadic.cpp @@ -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 +#include + +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 > +)); + diff --git a/test/custom_ccs/member_ccs.cpp b/test/custom_ccs/member_ccs.cpp new file mode 100644 index 0000000..727b38b --- /dev/null +++ b/test/custom_ccs/member_ccs.cpp @@ -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 +#include +#include +#include + +#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, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer, cc>::type + > +)); + diff --git a/test/custom_ccs/member_ccs_exact.cpp b/test/custom_ccs/member_ccs_exact.cpp new file mode 100644 index 0000000..2decf14 --- /dev/null +++ b/test/custom_ccs/member_ccs_exact.cpp @@ -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 +#include +#include +#include + +#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, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer >::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer >::type, cc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer, cc>::type, dc > +)); + diff --git a/test/custom_ccs/nonmember_ccs.cpp b/test/custom_ccs/nonmember_ccs.cpp new file mode 100644 index 0000000..98bf3d5 --- /dev/null +++ b/test/custom_ccs/nonmember_ccs.cpp @@ -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 +#include +#include +#include +#include +#include + +#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, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::function_pointer, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::function_reference, cc>::type + > +)); + diff --git a/test/custom_ccs/nonmember_ccs_exact.cpp b/test/custom_ccs/nonmember_ccs_exact.cpp new file mode 100644 index 0000000..31f73c0 --- /dev/null +++ b/test/custom_ccs/nonmember_ccs_exact.cpp @@ -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 +#include +#include +#include +#include +#include + +#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,cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_pointer,cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_reference,cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_pointer >::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_type, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_pointer,cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_reference,cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_pointer >::type, cc > +)); + + + diff --git a/test/decomposition/class_type_transform.cpp b/test/decomposition/class_type_transform.cpp new file mode 100644 index 0000000..f007a40 --- /dev/null +++ b/test/decomposition/class_type_transform.cpp @@ -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 +#include + +#include +#include +#include +#include + +#include +#include + +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 > + ,1 >::type, C* > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::components > > + ,1 >::type, C** > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::components > + ,1 >::type, X > +)); + +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::parameter_types > + ,0 >::type, C* > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::parameter_types > > + ,0 >::type, C** > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::parameter_types > + ,0 >::type, X > +)); + + + + diff --git a/test/decomposition/components.cpp b/test/decomposition/components.cpp new file mode 100644 index 0000000..60cebde --- /dev/null +++ b/test/decomposition/components.cpp @@ -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 +#include +#include + +#include + +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::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components::types, mpl::vector > +)); + diff --git a/test/decomposition/components_seq.cpp b/test/decomposition/components_seq.cpp new file mode 100644 index 0000000..ad5f590 --- /dev/null +++ b/test/decomposition/components_seq.cpp @@ -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 + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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 c; + + +// front +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::front::type, C > )); + +// back +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::back::type, int > )); + +// at +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c::type, C > )); +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c::type, C & > )); +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c::type, int > )); + +// begin/end +BOOST_MPL_ASSERT(( mpl::equal< c, mpl::vector > )); + + +// clear +BOOST_MPL_ASSERT(( mpl::equal< mpl::clear, mpl::vector<> > )); + +// push_front +BOOST_MPL_ASSERT(( mpl::equal< mpl::push_front::type, mpl::vector > )); + +// pop_front +BOOST_MPL_ASSERT(( mpl::equal< mpl::pop_front::type, mpl::vector > )); + +// push_back +BOOST_MPL_ASSERT(( mpl::equal< mpl::push_back::type, mpl::vector > )); + +// pop_back +BOOST_MPL_ASSERT(( mpl::equal< mpl::pop_back::type, mpl::vector > )); + + +// size +BOOST_MPL_ASSERT_RELATION( ::boost::mpl::size::value, ==, 3 ); + +// empty +BOOST_MPL_ASSERT_NOT(( mpl::empty )); +BOOST_MPL_ASSERT(( mpl::empty< mpl::clear > )); + diff --git a/test/decomposition/function_arity.cpp b/test/decomposition/function_arity.cpp new file mode 100644 index 0000000..219c2c6 --- /dev/null +++ b/test/decomposition/function_arity.cpp @@ -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 + +#include + +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::value, ==, 0 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 1 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 2 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 1 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 2 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 3 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 4 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity::value, ==, 1 ); + diff --git a/test/decomposition/function_arity_fail.cpp b/test/decomposition/function_arity_fail.cpp new file mode 100644 index 0000000..39a7c74 --- /dev/null +++ b/test/decomposition/function_arity_fail.cpp @@ -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 + + +namespace ft = boost::function_types; + +class C; + +typedef ft::function_arity::type error_1; +typedef ft::function_arity::type error_2; +typedef ft::function_arity::type error_3; + diff --git a/test/decomposition/parameter_types.cpp b/test/decomposition/parameter_types.cpp new file mode 100644 index 0000000..5feb1a8 --- /dev/null +++ b/test/decomposition/parameter_types.cpp @@ -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 +#include +#include + +#include + + +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, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types::type, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types, mpl::vector<> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types, mpl::vector > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types, mpl::vector > +)); diff --git a/test/decomposition/parameter_types_fail.cpp b/test/decomposition/parameter_types_fail.cpp new file mode 100644 index 0000000..d23e891 --- /dev/null +++ b/test/decomposition/parameter_types_fail.cpp @@ -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 + + +namespace ft = boost::function_types; + +class C; + +typedef ft::parameter_types::type error_1; +typedef ft::parameter_types::type error_2; +typedef ft::parameter_types::type error_3; + diff --git a/test/decomposition/result_type.cpp b/test/decomposition/result_type.cpp new file mode 100644 index 0000000..8f1157d --- /dev/null +++ b/test/decomposition/result_type.cpp @@ -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 +#include + +#include + + +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::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,int&> +)); + +BOOST_MPL_ASSERT(( + boost::is_same::type,int const&> +)); + diff --git a/test/decomposition/result_type_fail.cpp b/test/decomposition/result_type_fail.cpp new file mode 100644 index 0000000..c701e57 --- /dev/null +++ b/test/decomposition/result_type_fail.cpp @@ -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 + + +namespace ft = boost::function_types; + +class C; + +typedef ft::result_type::type error_1; +typedef ft::result_type::type error_2; +typedef ft::result_type::type error_3; + diff --git a/test/reconfiguration/cc_preprocessing.cpp b/test/reconfiguration/cc_preprocessing.cpp new file mode 100644 index 0000000..889645d --- /dev/null +++ b/test/reconfiguration/cc_preprocessing.cpp @@ -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" + diff --git a/test/reconfiguration/partial_arity_preprocessing.cpp b/test/reconfiguration/partial_arity_preprocessing.cpp new file mode 100644 index 0000000..bd58cf9 --- /dev/null +++ b/test/reconfiguration/partial_arity_preprocessing.cpp @@ -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" + diff --git a/test/reconfiguration/preprocessing_mode.cpp b/test/reconfiguration/preprocessing_mode.cpp new file mode 100644 index 0000000..d6601c4 --- /dev/null +++ b/test/reconfiguration/preprocessing_mode.cpp @@ -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" + diff --git a/test/reconfiguration/simple_test.hpp b/test/reconfiguration/simple_test.hpp new file mode 100644 index 0000000..5b62a0b --- /dev/null +++ b/test/reconfiguration/simple_test.hpp @@ -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 +#include +#include +#include + +#include +#include +#include + +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_components; +typedef ft::components mfp_components; + +BOOST_MPL_ASSERT(( + mpl::equal< func_components::types, mpl::vector > +)); +BOOST_MPL_ASSERT_RELATION( + ::func_components::function_arity::value, ==, 1 +); + +BOOST_MPL_ASSERT(( + boost::is_same< ft::function_type< mpl::vector >::type, func > +)); + + +BOOST_MPL_ASSERT(( + mpl::equal< mfp_components::types, mpl::vector > +)); +BOOST_MPL_ASSERT_RELATION( + ::mfp_components::function_arity::value, ==, 2 +); + +BOOST_MPL_ASSERT(( + boost::is_same< ft::member_function_pointer< mpl::vector >::type, mem_func_ptr > +)); + + diff --git a/test/synthesis/cv_function_synthesis.cpp b/test/synthesis/cv_function_synthesis.cpp new file mode 100644 index 0000000..b80e854 --- /dev/null +++ b/test/synthesis/cv_function_synthesis.cpp @@ -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 +#include + +#include + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +template +void test_non_cv(T C::*) +{ + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( + boost::is_same< + ft::function_type< mpl::vector, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); +} + +template +void test_c_non_v(T C::*) +{ + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( + boost::is_same< + ft::function_type< mpl::vector, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); +} + +template +void test_v_non_c(T C::*) +{ + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT(( + boost::is_same< + ft::function_type< mpl::vector, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); +} + +template +void test_cv(T C::*) +{ + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( + boost::is_same< + ft::function_type< mpl::vector, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector, + ft::tag >::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); +} + diff --git a/test/synthesis/function_pointer.cpp b/test/synthesis/function_pointer.cpp new file mode 100644 index 0000000..1150934 --- /dev/null +++ b/test/synthesis/function_pointer.cpp @@ -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 +#include +#include +#include + +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 >::type, expected > +)); + diff --git a/test/synthesis/function_reference.cpp b/test/synthesis/function_reference.cpp new file mode 100644 index 0000000..92fa714 --- /dev/null +++ b/test/synthesis/function_reference.cpp @@ -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 +#include +#include +#include + +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 >::type, expected > +)); + diff --git a/test/synthesis/function_type.cpp b/test/synthesis/function_type.cpp new file mode 100644 index 0000000..bb08ce7 --- /dev/null +++ b/test/synthesis/function_type.cpp @@ -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 +#include +#include +#include + +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 >::type, expected > +)); + diff --git a/test/synthesis/mem_func_ptr_cv1.cpp b/test/synthesis/mem_func_ptr_cv1.cpp new file mode 100644 index 0000000..b1f70be --- /dev/null +++ b/test/synthesis/mem_func_ptr_cv1.cpp @@ -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 +#include +#include +#include + +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 >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector >::type + , expected4 > +)); + +// implicit & explicit/overrides + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector + , ft::tag >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector + , ft::const_qualified >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector + , ft::volatile_qualified >::type + , expected4 > +)); + + diff --git a/test/synthesis/mem_func_ptr_cv2.cpp b/test/synthesis/mem_func_ptr_cv2.cpp new file mode 100644 index 0000000..007efa0 --- /dev/null +++ b/test/synthesis/mem_func_ptr_cv2.cpp @@ -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 +#include +#include +#include + +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 >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector >::type + , expected4 > +)); + +// implicit & explicit/overrides + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector + , ft::tag >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector + , ft::const_qualified >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector + , ft::volatile_qualified >::type + , expected4 > +)); + + diff --git a/test/synthesis/mem_func_ptr_cv_ptr_to_this.cpp b/test/synthesis/mem_func_ptr_cv_ptr_to_this.cpp new file mode 100644 index 0000000..1b6d906 --- /dev/null +++ b/test/synthesis/mem_func_ptr_cv_ptr_to_this.cpp @@ -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 +#include +#include +#include + +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 >::type + , expected > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector >::type + , expected > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector >::type + , expected > +)); + + + diff --git a/test/synthesis/member_function_pointer.cpp b/test/synthesis/member_function_pointer.cpp new file mode 100644 index 0000000..6234c47 --- /dev/null +++ b/test/synthesis/member_function_pointer.cpp @@ -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 +#include +#include +#include + +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 >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector + , ft::const_qualified >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector + , ft::volatile_qualified >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector, + ft::tag >::type + , expected4 > +)); + diff --git a/test/synthesis/member_object_pointer.cpp b/test/synthesis/member_object_pointer.cpp new file mode 100644 index 0000000..65af741 --- /dev/null +++ b/test/synthesis/member_object_pointer.cpp @@ -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 +#include +#include +#include + +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 >::type + , expected > +)); + diff --git a/test/synthesis/transformation.cpp b/test/synthesis/transformation.cpp new file mode 100644 index 0000000..3885647 --- /dev/null +++ b/test/synthesis/transformation.cpp @@ -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 +#include + +#include +#include +#include +#include + +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::type > )); +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type::type > )); +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type::type > )); +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference::type > )); + +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer::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::type > )); +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type::type > )); +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type::type > )); +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference::type > )); + +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer::type > )); + + + diff --git a/test/synthesis/variadic_function_synthesis.cpp b/test/synthesis/variadic_function_synthesis.cpp new file mode 100644 index 0000000..d35b319 --- /dev/null +++ b/test/synthesis/variadic_function_synthesis.cpp @@ -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 +#include +#include + +#include +#include +#include +#include + +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, ft::variadic>::type, expected_v_1 +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_type, ft::non_variadic>::type, expected_nv_1 +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_pointer, ft::variadic>::type, expected_v_1 * +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_pointer, ft::non_variadic>::type + , expected_nv_1 * +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_reference, ft::variadic>::type, expected_v_1 & +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_reference, ft::non_variadic>::type + , expected_nv_1 & +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::member_function_pointer, ft::variadic>::type + , expected_v_2 +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::member_function_pointer, ft::non_variadic>::type + , expected_nv_2 +> )); +