diff options
Diffstat (limited to 'src/boost/libs/function_types')
64 files changed, 4564 insertions, 0 deletions
diff --git a/src/boost/libs/function_types/CMakeLists.txt b/src/boost/libs/function_types/CMakeLists.txt new file mode 100644 index 000000000..705a7bb9e --- /dev/null +++ b/src/boost/libs/function_types/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright 2019 Mike Dev +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt +# +# NOTE: CMake support for Boost.FunctionTypes is currently experimental at best +# and the interface is likely to change in the future + +cmake_minimum_required( VERSION 3.5 ) +project( BoostFunctionTypes LANGUAGES CXX ) + +add_library( boost_function_types INTERFACE ) +add_library( Boost::function_types ALIAS boost_function_types ) + +target_include_directories( boost_function_types INTERFACE include ) + +target_link_libraries( boost_function_types + INTERFACE + Boost::config + Boost::core + Boost::detail + Boost::mpl + Boost::preprocessor + Boost::type_traits +) + diff --git a/src/boost/libs/function_types/build/Jamfile b/src/boost/libs/function_types/build/Jamfile new file mode 100644 index 000000000..38b185a22 --- /dev/null +++ b/src/boost/libs/function_types/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. + +actions wave +{ + $(>[1]) -S../../.. $(>[2]) -o $(<) +} + +W = ../../../tools/wave/build//wave ; + +make arity_loops + : preprocess_arity_loops.cpp $(W) : wave : <location>build/timestamps + ; + +make encoding + : preprocess_encoding.cpp $(W) : wave : <location>build/timestamps + ; + + +make cc_names + : preprocess_cc_names.cpp $(W) : wave : <location>build/timestamps + ; + +explicit arity_loops encoding cc_names ; + diff --git a/src/boost/libs/function_types/build/preprocess_arity_loops.cpp b/src/boost/libs/function_types/build/preprocess_arity_loops.cpp new file mode 100644 index 000000000..d39b65cf6 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/preprocessor/seq/cat.hpp> +# include <boost/preprocessor/stringize.hpp> + +# if BOOST_PP_NIL // enable dependency scanning for dynamically included files +# include <boost/function_types/detail/encoding/def.hpp> +# include <boost/function_types/detail/components_impl/master.hpp> +# include <boost/function_types/detail/synthesize_impl/master.hpp> +# include <boost/function_types/detail/classifier_impl/master.hpp> +# endif + +# pragma wave option(line: 0, preserve: 2) +timestamp file +# pragma wave option(output: null) + +# define BOOST_FT_PREPROCESSING_MODE + +# define BOOST_FT_HEADER \ + BOOST_PP_SEQ_CAT((arity)(BOOST_FT_MAX_ARITY)(_)(BOOST_FT_mfp)).hpp + #define BOOST_FT_OUT_FILE \ + BOOST_PP_STRINGIZE(../../../BOOST_FT_al_path/BOOST_FT_HEADER) + +# define BOOST_FT_al_path boost/function_types/detail/components_impl +# include __FILE__ +# undef BOOST_FT_al_path + +# define BOOST_FT_al_path boost/function_types/detail/synthesize_impl +# include __FILE__ +# undef BOOST_FT_al_path + +# define BOOST_FT_al_path boost/function_types/detail/classifier_impl +# include __FILE__ +# undef BOOST_FT_al_path + +#elif !defined(BOOST_FT_mfp) + +# define BOOST_FT_mfp 0 +# include __FILE__ +# undef BOOST_FT_mfp + +# define BOOST_FT_mfp 1 +# include __FILE__ +# undef BOOST_FT_mfp + +#elif !defined(BOOST_FT_MAX_ARITY) + +# define BOOST_FT_FROM_ARITY 0 +# define BOOST_FT_MAX_ARITY 10 +# include __FILE__ + +# define BOOST_FT_FROM_ARITY 10 +# define BOOST_FT_MAX_ARITY 20 +# include __FILE__ + +# define BOOST_FT_FROM_ARITY 20 +# define BOOST_FT_MAX_ARITY 30 +# include __FILE__ + +# define BOOST_FT_FROM_ARITY 30 +# define BOOST_FT_MAX_ARITY 40 +# include __FILE__ + +# define BOOST_FT_FROM_ARITY 40 +# define BOOST_FT_MAX_ARITY 50 +# include __FILE__ + +#else + +# pragma message(generating BOOST_FT_OUT_FILE) +# pragma wave option(preserve: 2, output: BOOST_FT_OUT_FILE) +# include <boost/function_types/detail/pp_arity_loop.hpp> +# undef BOOST_FT_MAX_ARITY + +#endif + diff --git a/src/boost/libs/function_types/build/preprocess_cc_names.cpp b/src/boost/libs/function_types/build/preprocess_cc_names.cpp new file mode 100644 index 000000000..803667c55 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/function_types/detail/pp_cc_loop/master.hpp> +#pragma wave option(output: null) +#undef BOOST_FT_OUT_FILE + diff --git a/src/boost/libs/function_types/build/preprocess_encoding.cpp b/src/boost/libs/function_types/build/preprocess_encoding.cpp new file mode 100644 index 000000000..886bec33b --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/function_types/detail/pp_tags/master.hpp> +#pragma wave option(output: null) +#undef BOOST_FT_OUT_FILE + +#define BOOST_FT_OUT_FILE \ + "../../../boost/function_types/detail/pp_variate_loop/preprocessed.hpp" +#pragma message(generating BOOST_FT_OUT_FILE) +#pragma wave option(output: BOOST_FT_OUT_FILE, preserve: 2) +#include <boost/function_types/detail/pp_variate_loop/master.hpp> +#pragma wave option(output: null) +#undef BOOST_FT_OUT_FILE + +#define BOOST_FT_OUT_FILE \ + "../../../boost/function_types/detail/pp_retag_default_cc/preprocessed.hpp" +#pragma message(generating BOOST_FT_OUT_FILE) +#pragma wave option(output: BOOST_FT_OUT_FILE, preserve: 2) +#include <boost/function_types/detail/pp_retag_default_cc/master.hpp> +#pragma wave option(output: null) + +#undef BOOST_FT_OUT_FILE + + diff --git a/src/boost/libs/function_types/build/timestamps/arity_loops b/src/boost/libs/function_types/build/timestamps/arity_loops new file mode 100644 index 000000000..f91091c8d --- /dev/null +++ b/src/boost/libs/function_types/build/timestamps/arity_loops @@ -0,0 +1 @@ +timestamp file diff --git a/src/boost/libs/function_types/build/timestamps/cc_names b/src/boost/libs/function_types/build/timestamps/cc_names new file mode 100644 index 000000000..f91091c8d --- /dev/null +++ b/src/boost/libs/function_types/build/timestamps/cc_names @@ -0,0 +1 @@ +timestamp file diff --git a/src/boost/libs/function_types/build/timestamps/encoding b/src/boost/libs/function_types/build/timestamps/encoding new file mode 100644 index 000000000..f91091c8d --- /dev/null +++ b/src/boost/libs/function_types/build/timestamps/encoding @@ -0,0 +1 @@ +timestamp file diff --git a/src/boost/libs/function_types/example/Jamfile b/src/boost/libs/function_types/example/Jamfile new file mode 100644 index 000000000..08ab43dfe --- /dev/null +++ b/src/boost/libs/function_types/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 + : <include>. ; # needed for Boost.PP file iteration with some compilers + +exe macro_type_args_example : macro_type_args_example.cpp ; + + diff --git a/src/boost/libs/function_types/example/detail/param_type.hpp b/src/boost/libs/function_types/example/detail/param_type.hpp new file mode 100644 index 000000000..7c0fd5f2d --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/config.hpp> + +#include <boost/type_traits/add_const.hpp> +#include <boost/type_traits/add_reference.hpp> + +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/identity.hpp> + +#include <boost/mpl/aux_/lambda_support.hpp> +// #include <boost/type_traits/detail/template_arity_spec.hpp> + +// namespace boost +namespace example +{ + namespace mpl = boost::mpl; + + // namespace utility + // { + namespace param_type_detail + { + template<typename T> + struct by_ref_cond + { + typedef by_ref_cond type; + BOOST_STATIC_CONSTANT(bool,value = sizeof(void*) < sizeof(T)); + }; + + template<typename T> + struct add_ref_to_const + : boost::add_reference< typename boost::add_const<T>::type > + { }; + } + + template<typename T> + struct param_type + : mpl::eval_if< param_type_detail::by_ref_cond<T> + , param_type_detail::add_ref_to_const<T>, mpl::identity<T> > + { + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,param_type,(T)) + }; + // } + // BOOST_TT_AUX_TEMPLATE_ARITY_SPEC(1,utility::param_type) +} + +#endif + diff --git a/src/boost/libs/function_types/example/fast_mem_fn.hpp b/src/boost/libs/function_types/example/fast_mem_fn.hpp new file mode 100644 index 000000000..2587c180f --- /dev/null +++ b/src/boost/libs/function_types/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://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm +// +// [Dimov2] Dimov, P. Documentation of boost::mem_fn +// http://www.boost.org/libs/bind/mem_fn.html + +#ifndef BOOST_EXAMPLE_FAST_MEM_FN_HPP_INCLUDED +#ifndef BOOST_PP_IS_ITERATING + + +#include <boost/function_types/result_type.hpp> +#include <boost/function_types/function_arity.hpp> +#include <boost/function_types/parameter_types.hpp> +#include <boost/function_types/is_member_function_pointer.hpp> + +#include <boost/mpl/transform_view.hpp> +#include <boost/mpl/begin.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/deref.hpp> + +#include <boost/utility/enable_if.hpp> + +#include "detail/param_type.hpp" + +namespace example +{ + + namespace ft = boost::function_types; + namespace mpl = boost::mpl; + using namespace mpl::placeholders; + + // the functor class template + template< typename MFPT, MFPT MemberFunction + , size_t Arity = ::example::ft::function_arity<MFPT>::value + > + struct fast_mem_fn; + + // ------- ---- --- -- - - - - + + // deduce type and capture compile time value + #define BOOST_EXAMPLE_FAST_MEM_FN(mfp) \ + ::example::make_fast_mem_fn(mfp).make_fast_mem_fn<mfp>() + + template<typename MFPT> + struct fast_mem_fn_maker + { + template<MFPT Callee> + fast_mem_fn<MFPT,Callee> make_fast_mem_fn() + { + return fast_mem_fn<MFPT,Callee>(); + } + }; + + template<typename MFPT> + typename boost::enable_if<boost::is_member_function_pointer<MFPT>, + fast_mem_fn_maker<MFPT> >::type + make_fast_mem_fn(MFPT) + { + return fast_mem_fn_maker<MFPT>(); + } + + + // ------- ---- --- -- - - - - + + namespace detail + { + // by-value forwarding optimization + template<typename T> + struct parameter_types + : mpl::transform_view<ft::parameter_types<T>,param_type<_> > + { }; + } + + // ------- ---- --- -- - - - - + + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn<MFPT, MemberFunction, 1> + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type<MFPT>::type result_type; + typedef detail::parameter_types<MFPT> parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin<parameter_types>::type i0; + public: + // forwarding function call operator + result_type operator()( typename mpl::deref<i0>::type a0) const + { + return (a0.*MemberFunction)(); + }; + }; + + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn<MFPT, MemberFunction, 2> + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type<MFPT>::type result_type; + typedef detail::parameter_types<MFPT> parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin<parameter_types>::type i0; + typedef typename mpl::next<i0>::type i1; + public: + // forwarding function call operator + result_type operator()( typename mpl::deref<i0>::type a0 + , typename mpl::deref<i1>::type a1) const + { + return (a0.*MemberFunction)(a1); + }; + }; + + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn<MFPT, MemberFunction, 3> + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type<MFPT>::type result_type; + typedef detail::parameter_types<MFPT> parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin<parameter_types>::type i0; + typedef typename mpl::next<i0>::type i1; + typedef typename mpl::next<i1>::type i2; + public: + // forwarding function call operator + result_type operator()( typename mpl::deref<i0>::type a0 + , typename mpl::deref<i1>::type a1 + , typename mpl::deref<i2>::type a2) const + { + return (a0.*MemberFunction)(a1,a2); + }; + }; + + // ... +} + +// ------- ---- --- -- - - - - + +// preprocessor-based code generator to continue the repetitive part, above + +#include <boost/preprocessor/cat.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/iteration/iterate.hpp> +#include <boost/preprocessor/iteration/local.hpp> +#include <boost/preprocessor/repetition/enum_shifted_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> + +namespace example +{ + #if BOOST_FT_MAX_ARITY >= 4 + # define BOOST_PP_FILENAME_1 "fast_mem_fn.hpp" + # define BOOST_PP_ITERATION_LIMITS (4,BOOST_FT_MAX_ARITY) + # include BOOST_PP_ITERATE() + #endif +} + +#define BOOST_EXAMPLE_FAST_MEM_FN_HPP_INCLUDED +#else + + #define N BOOST_PP_FRAME_ITERATION(1) + template< typename MFPT, MFPT MemberFunction > + struct fast_mem_fn<MFPT, MemberFunction, N > + { + // decompose the result and the parameter types (public for introspection) + typedef typename ft::result_type<MFPT>::type result_type; + typedef detail::parameter_types<MFPT> parameter_types; + private: + // iterate the parameter types + typedef typename mpl::begin<parameter_types>::type i0; + #define BOOST_PP_LOCAL_LIMITS (0,N-2) + #define BOOST_PP_LOCAL_MACRO(j) \ + typedef typename mpl::next< i ## j >::type BOOST_PP_CAT(i,BOOST_PP_INC(j)) ; + #include BOOST_PP_LOCAL_ITERATE() + public: + // forwarding function call operator + result_type operator()( + BOOST_PP_ENUM_BINARY_PARAMS(N, typename mpl::deref<i,>::type a) ) const + { + return (a0.*MemberFunction)(BOOST_PP_ENUM_SHIFTED_PARAMS(N,a)); + }; + }; + #undef N + +#endif +#endif + diff --git a/src/boost/libs/function_types/example/fast_mem_fn_example.cpp b/src/boost/libs/function_types/example/fast_mem_fn_example.cpp new file mode 100644 index 000000000..381ee146e --- /dev/null +++ b/src/boost/libs/function_types/example/fast_mem_fn_example.cpp @@ -0,0 +1,122 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ +// See fast_mem_fn.hpp in this directory for details. + +#include <vector> +#include <cassert> +#include <iostream> +#include <algorithm> +#include <functional> + +#include <boost/timer.hpp> +#include <boost/mem_fn.hpp> + +#include "fast_mem_fn.hpp" + +// test class that holds a single integer with getter function +class test +{ + int val_id; +public: + + explicit test(int id) + : val_id(id) + { } + + int id() const + { return val_id; } + +}; + +// STL style comparator that applies the CriterionExtractor function to both +// operands and compares the results with Comparator +template<typename CriterionExtractor, typename Comparator> +class test_compare +{ + CriterionExtractor fnc_criterion; + Comparator fnc_compare; +public: + + explicit test_compare(CriterionExtractor criterion, Comparator compare) + : fnc_criterion(criterion) + , fnc_compare(compare) + { } + + template<typename T> + inline bool operator()(T const & lhs, T const & rhs) const + { + return fnc_compare(fnc_criterion(lhs),fnc_criterion(rhs)); + } +}; + +// helper function to construct an instance of the test_compare comparator. +template<typename CriterionExtractor, typename Comparator> +test_compare<CriterionExtractor,Comparator> +make_test_compare(CriterionExtractor criterion, Comparator compare) +{ + return test_compare<CriterionExtractor,Comparator>(criterion,compare); +} + +// the test case: sort N test objects by id +// +// the objects are in ascending order before the test run and in descending +// order after it + +static const unsigned N = 2000000; + +typedef std::vector<test> test_vector; + + +void setup_test(test_vector & v) +{ + v.clear(); + v.reserve(N); + for (unsigned i = 0; i < N; ++i) + v.push_back(test(i)); +} + +template<typename F> void do_test(test_vector & v, F criterion) +{ + std::sort(v.begin(),v.end(),make_test_compare(criterion,std::greater<int>())); + assert(v.begin()->id() == N-1); +} + + +// compare performance with boost::mem_fn +int main() +{ + test_vector v; + boost::timer t; + double time1, time2; + + std::cout << + "Test case: sorting " << N << " objects.\n\n" + "Criterion accessor called with | elasped seconds\n" + "-------------------------------|----------------" << std::endl; + + setup_test(v); + t.restart(); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1400) + do_test(v, BOOST_EXAMPLE_FAST_MEM_FN(& test::id)); +#else // MSVC<8 does not like the implementation of the deduction macro: + do_test(v, ::example::fast_mem_fn< int (test::*)() const, & test::id >()); +#endif + 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/src/boost/libs/function_types/example/interface.hpp b/src/boost/libs/function_types/example/interface.hpp new file mode 100644 index 000000000..cadf740d2 --- /dev/null +++ b/src/boost/libs/function_types/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 <cstddef> + +#include <boost/function_types/function_pointer.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +#include <boost/config.hpp> +#include <boost/detail/workaround.hpp> + +#include <boost/utility/addressof.hpp> + +#include <boost/mpl/at.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/joint_view.hpp> +#include <boost/mpl/single_view.hpp> +#include <boost/mpl/transform_view.hpp> + +#include <boost/preprocessor/seq/seq.hpp> +#include <boost/preprocessor/seq/enum.hpp> +#include <boost/preprocessor/seq/elem.hpp> +#include <boost/preprocessor/seq/size.hpp> +#include <boost/preprocessor/tuple/elem.hpp> +#include <boost/preprocessor/arithmetic/dec.hpp> +#include <boost/preprocessor/arithmetic/inc.hpp> +#include <boost/preprocessor/facilities/empty.hpp> +#include <boost/preprocessor/facilities/identity.hpp> +#include <boost/preprocessor/punctuation/comma_if.hpp> +#include <boost/preprocessor/iteration/local.hpp> +#include <boost/preprocessor/repetition/enum.hpp> +#include <boost/preprocessor/repetition/enum_params.hpp> +#include <boost/preprocessor/repetition/enum_binary_params.hpp> +#include <boost/preprocessor/repetition/enum_trailing_params.hpp> + +#include "detail/param_type.hpp" + +namespace example +{ + namespace ft = boost::function_types; + namespace mpl = boost::mpl; + using namespace mpl::placeholders; + + // join a single type and an MPL-sequence + // in some ways similar to mpl::push_front (but mpl::push_front requires + // an MPL Extensible Sequence and this template does not) + template<typename T, typename Seq> + struct concat_view + : mpl::joint_view<mpl::single_view<T>, Seq> + { }; + + // metafunction returning a function pointer type for a vtable entry + template<typename Inf> + struct vtable_entry + : ft::function_pointer + < concat_view< typename Inf::result, mpl::transform_view< + typename Inf::params, param_type<_> > > > + { }; + + // the expression '& member<MetaInfo,Tag>::wrap<& Class::Function> ' in an + // assignment context binds the member function Function of Class with the + // properties described by MetaInfo and Tag to the corresponding vtable + // entry + template<typename Inf, typename Tag> + struct member + { + typedef typename ft::member_function_pointer + < concat_view<typename Inf::result,typename Inf::params>,Tag + >::type + mem_func_ptr; + + typedef typename mpl::at_c<typename Inf::params,0>::type context; + + template<mem_func_ptr MemFuncPtr> + static typename Inf::result wrap(void* c) + { + return (reinterpret_cast<context*>(c)->*MemFuncPtr)(); + } + template<mem_func_ptr MemFuncPtr, typename T0> + static typename Inf::result wrap(void* c, T0 a0) + { + return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0); + } + template<mem_func_ptr MemFuncPtr, typename T0, typename T1> + static typename Inf::result wrap(void* c, T0 a0, T1 a1) + { + return (reinterpret_cast<context*>(c)->*MemFuncPtr)(a0,a1); + } + // continue with the preprocessor (the scheme should be clear, by now) + #define BOOST_PP_LOCAL_MACRO(n) \ + template<mem_func_ptr MemFuncPtr, BOOST_PP_ENUM_PARAMS(n,typename T)> \ + static typename Inf::result wrap(void* c, \ + BOOST_PP_ENUM_BINARY_PARAMS(n,T,a)) \ + { \ + return (reinterpret_cast<context*>(c)->*MemFuncPtr)( \ + BOOST_PP_ENUM_PARAMS(n,a) ); \ + } + #define BOOST_PP_LOCAL_LIMITS (3,BOOST_FT_MAX_ARITY-1) + #include BOOST_PP_LOCAL_ITERATE() + }; + + // extract a parameter by index + template<typename Inf, std::size_t Index> + struct param + : param_type< typename mpl::at_c< typename Inf::params,Index>::type > + { }; +} + +// the interface definition on the client's side +#define BOOST_EXAMPLE_INTERFACE(name,def) \ + class name \ + { \ + struct vtable \ + { \ + BOOST_EXAMPLE_INTERFACE__MEMBERS(def,VTABLE) \ + }; \ + \ + vtable const * ptr_vtable; \ + void * ptr_that; \ + \ + template<class T> struct vtable_holder \ + { \ + static vtable const val_vtable; \ + }; \ + \ + public: \ + \ + template<class T> \ + inline name (T & that) \ + : ptr_vtable(& vtable_holder<T>::val_vtable) \ + , ptr_that(boost::addressof(that)) \ + { } \ + \ + BOOST_EXAMPLE_INTERFACE__MEMBERS(def,FUNCTION) \ + }; \ + \ + template<typename T> \ + name ::vtable const name ::vtable_holder<T>::val_vtable \ + = { BOOST_EXAMPLE_INTERFACE__MEMBERS(def,INIT_VTABLE) } + + +#ifdef BOOST_PP_NIL // never defined -- a comment with syntax highlighting + +BOOST_EXAMPLE_INTERFACE( interface_x, + (( a_func, (void)(int), const_qualified )) + (( another_func, (int), non_const )) +); + +// expands to: +class interface_x +{ + struct vtable + { + // meta information for first function + template<typename T = void*> struct inf0 + { + typedef void result; + typedef ::boost::mpl::vector< T, int > params; + }; + // function pointer with void* context pointer and parameters optimized + // for forwarding + ::example::vtable_entry<inf0<> >::type func0; + + // second function + template<typename T = void*> struct inf1 + { + typedef int result; + typedef ::boost::mpl::vector< T > params; + }; + ::example::vtable_entry<inf1<> >::type func1; + }; + + // data members + vtable const * ptr_vtable; + void * ptr_that; + + // this template is instantiated for every class T this interface is created + // from, causing the compiler to emit an initialized vtable for this type + // (see aggregate assignment, below) + template<class T> struct vtable_holder + { + static vtable const val_vtable; + }; + +public: + + // converting ctor, creates an interface from an arbitrary class + template<class T> + inline interface_x (T & that) + : ptr_vtable(& vtable_holder<T>::val_vtable) + , ptr_that(boost::addressof(that)) + { } + + // the member functions from the interface definition, parameters are + // optimized for forwarding + + inline vtable::inf0<> ::result a_func ( + ::example::param<vtable::inf0<>,1>::type p0) const + { + return ptr_vtable-> func0(ptr_that , p0); + } + + inline vtable::inf1<> ::result another_func () + { + return ptr_vtable-> func1(ptr_that ); + } +}; + +template<typename T> +interface_x ::vtable const interface_x ::vtable_holder<T>::val_vtable = +{ + // instantiate function templates that wrap member function pointers (which + // are known at compile time) by taking their addresses in assignment to + // function pointer context + & ::example::member< vtable::inf0<T>, ::example::ft:: const_qualified > + ::template wrap < &T:: a_func > +, & ::example::member< vtable::inf1<T>, ::example::ft:: non_const > + ::template wrap < &T:: another_func > +}; +#endif + +// preprocessing code details + +// iterate all of the interface's members and invoke a macro (prefixed with +// BOOST_EXAMPLE_INTERFACE_) +#define BOOST_EXAMPLE_INTERFACE__MEMBERS(seq,macro) \ + BOOST_PP_REPEAT(BOOST_PP_SEQ_SIZE(seq), \ + BOOST_EXAMPLE_INTERFACE__ ## macro,seq) + +// extract signature sequence from entry +#define BOOST_EXAMPLE_INTERFACE__VTABLE(z,i,seq) \ + BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i, \ + BOOST_PP_TUPLE_ELEM(3,1,BOOST_PP_SEQ_ELEM(i,seq))) + +// split the signature sequence result/params and insert T at the beginning of +// the params part +#define BOOST_EXAMPLE_INTERFACE__VTABLE_I(z,i,seq) \ + BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i, \ + BOOST_PP_SEQ_HEAD(seq),(T)BOOST_PP_SEQ_TAIL(seq)) + +// emit the meta information structure and function pointer declaration +#define BOOST_EXAMPLE_INTERFACE__VTABLE_II(z,i,result_type,param_types) \ + template<typename T = void*> \ + struct BOOST_PP_CAT(inf,i) \ + { \ + typedef result_type result; \ + typedef ::boost::mpl::vector< BOOST_PP_SEQ_ENUM(param_types) > params; \ + }; \ + ::example::vtable_entry<BOOST_PP_CAT(inf,i)<> >::type BOOST_PP_CAT(func,i); + +// extract tuple entry from sequence and precalculate the name of the function +// pointer variable +#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE(z,i,seq) \ + BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,BOOST_PP_CAT(func,i), \ + BOOST_PP_SEQ_ELEM(i,seq)) + +// emit a function pointer expression that encapsulates the corresponding +// member function of T +#define BOOST_EXAMPLE_INTERFACE__INIT_VTABLE_I(i,seq,func,desc) \ + BOOST_PP_COMMA_IF(i) & ::example::member< BOOST_PP_CAT(vtable::inf,i)<T>, \ + ::example::ft:: BOOST_PP_TUPLE_ELEM(3,2,desc) >::template wrap \ + < &T:: BOOST_PP_TUPLE_ELEM(3,0,desc) > + +// extract tuple entry from sequence +#define BOOST_EXAMPLE_INTERFACE__FUNCTION(z,i,seq) \ + BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,BOOST_PP_SEQ_ELEM(i,seq)) + +// precalculate function name, arity, name of meta info structure and cv- +// qualifiers +#define BOOST_EXAMPLE_INTERFACE__FUNCTION_I(z,i,desc) \ + BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i, \ + BOOST_PP_TUPLE_ELEM(3,0,desc), \ + BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(BOOST_PP_TUPLE_ELEM(3,1,desc))), \ + BOOST_PP_CAT(vtable::inf,i)<>, \ + BOOST_PP_CAT(BOOST_EXAMPLE_INTERFACE___,BOOST_PP_TUPLE_ELEM(3,2,desc)) \ + ) + +// emit the definition for a member function of the interface +#define BOOST_EXAMPLE_INTERFACE__FUNCTION_II(z,i,name,arity,types,cv) \ + inline types ::result name \ + (BOOST_PP_ENUM_ ## z (arity,BOOST_EXAMPLE_INTERFACE__PARAM,types)) cv() \ + { \ + return ptr_vtable-> BOOST_PP_CAT(func,i)(ptr_that \ + BOOST_PP_ENUM_TRAILING_PARAMS_Z(z,arity,p)); \ + } + +// emit a parameter of the function definition +#define BOOST_EXAMPLE_INTERFACE__PARAM(z,j,types) \ + ::example::param<types,BOOST_PP_INC(j)>::type BOOST_PP_CAT(p,j) + +// helper macros to map 'const_qualified' to 'const' an 'non_const' to '' +#define BOOST_EXAMPLE_INTERFACE___const_qualified BOOST_PP_IDENTITY(const) +#define BOOST_EXAMPLE_INTERFACE___non_const BOOST_PP_EMPTY + + diff --git a/src/boost/libs/function_types/example/interface_example.cpp b/src/boost/libs/function_types/example/interface_example.cpp new file mode 100644 index 000000000..6b7f8d946 --- /dev/null +++ b/src/boost/libs/function_types/example/interface_example.cpp @@ -0,0 +1,80 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ +// See interface.hpp in this directory for details. + +#include <iostream> +#include <typeinfo> + +#include "interface.hpp" + + +BOOST_EXAMPLE_INTERFACE( interface_x, + (( a_func, (void)(int) , const_qualified )) + (( a_func, (void)(long), const_qualified )) + (( another_func, (int) , non_const )) +); + + +// two classes that implement interface_x + +struct a_class +{ + void a_func(int v) const + { + std::cout << "a_class::void a_func(int v = " << v << ")" << std::endl; + } + + void a_func(long v) const + { + std::cout << "a_class::void a_func(long v = " << v << ")" << std::endl; + } + + int another_func() + { + std::cout << "a_class::another_func() = 3" << std::endl; + return 3; + } +}; + +struct another_class +{ + // note: overloaded a_func implemented as a function template + template<typename T> + void a_func(T v) const + { + std::cout << + "another_class::void a_func(T v = " << v << ")" + " [ T = " << typeid(T).name() << " ]" << std::endl; + } + + int another_func() + { + std::cout << "another_class::another_func() = 5" << std::endl; + return 5; + } +}; + + +// both classes above can be assigned to the interface variable and their +// member functions can be called through it +int main() +{ + a_class x; + another_class y; + + interface_x i(x); + i.a_func(12); + i.a_func(77L); + i.another_func(); + + i = y; + i.a_func(13); + i.a_func(21L); + i.another_func(); +} + diff --git a/src/boost/libs/function_types/example/interpreter.hpp b/src/boost/libs/function_types/example/interpreter.hpp new file mode 100644 index 000000000..72cd78b0e --- /dev/null +++ b/src/boost/libs/function_types/example/interpreter.hpp @@ -0,0 +1,189 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ +// +// This example implements a simple batch-style interpreter that is capable of +// calling functions previously registered with it. The parameter types of the +// functions are used to control the parsing of the input. +// +// Implementation description +// ========================== +// +// When a function is registered, an 'invoker' template is instantiated with +// the function's type. The 'invoker' fetches a value from the 'token_parser' +// for each parameter of the function into a tuple and finally invokes the the +// function with these values as arguments. The invoker's entrypoint, which +// is a function of the callable builtin that describes the function to call and +// a reference to the 'token_parser', is partially bound to the registered +// function and put into a map so it can be found by name during parsing. + +#include <map> +#include <string> +#include <stdexcept> + +#include <boost/token_iterator.hpp> +#include <boost/token_functions.hpp> + +#include <boost/lexical_cast.hpp> + +#include <boost/bind.hpp> +#include <boost/function.hpp> + +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/remove_reference.hpp> + +#include <boost/fusion/include/push_back.hpp> +#include <boost/fusion/include/cons.hpp> +#include <boost/fusion/include/invoke.hpp> + +#include <boost/mpl/begin.hpp> +#include <boost/mpl/end.hpp> +#include <boost/mpl/next.hpp> +#include <boost/mpl/deref.hpp> + +#include <boost/utility/enable_if.hpp> + +#include <boost/function_types/is_nonmember_callable_builtin.hpp> +#include <boost/function_types/parameter_types.hpp> + +namespace example +{ + namespace fusion = boost::fusion; + namespace ft = boost::function_types; + namespace mpl = boost::mpl; + + class interpreter + { + class token_parser; + typedef boost::function<void(token_parser &)> invoker_function; + typedef std::map<std::string, invoker_function> dictionary; + + dictionary map_invokers; + public: + // Registers a function with the interpreter. + template<typename Function> + typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> + >::type register_function(std::string const & name, Function f); + + // Parse input for functions to call. + void parse_input(std::string const & text) const; + + private: + template< typename Function + , class From = typename mpl::begin< ft::parameter_types<Function> >::type + , class To = typename mpl::end< ft::parameter_types<Function> >::type + > + struct invoker; + }; + + class interpreter::token_parser + { + typedef boost::token_iterator_generator< + boost::char_separator<char> >::type token_iterator; + + token_iterator itr_at, itr_to; + public: + + token_parser(token_iterator from, token_iterator to) + : itr_at(from), itr_to(to) + { } + + private: + template<typename T> + struct remove_cv_ref + : boost::remove_cv< typename boost::remove_reference<T>::type > + { }; + public: + // Returns a token of given type. + // We just apply boost::lexical_cast to whitespace separated string tokens + // for simplicity. + template<typename RequestedType> + typename remove_cv_ref<RequestedType>::type get() + { + if (! this->has_more_tokens()) + throw std::runtime_error("unexpected end of input"); + + try + { + typedef typename remove_cv_ref<RequestedType>::type result_type; + result_type result = boost::lexical_cast + <typename remove_cv_ref<result_type>::type>(*this->itr_at); + ++this->itr_at; + return result; + } + + catch (boost::bad_lexical_cast &) + { throw std::runtime_error("invalid argument: " + *this->itr_at); } + } + + // Any more tokens? + bool has_more_tokens() const { return this->itr_at != this->itr_to; } + }; + + template<typename Function, class From, class To> + struct interpreter::invoker + { + // add an argument to a Fusion cons-list for each parameter type + template<typename Args> + static inline + void apply(Function func, token_parser & parser, Args const & args) + { + typedef typename mpl::deref<From>::type arg_type; + typedef typename mpl::next<From>::type next_iter_type; + + interpreter::invoker<Function, next_iter_type, To>::apply + ( func, parser, fusion::push_back(args, parser.get<arg_type>()) ); + } + }; + + template<typename Function, class To> + struct interpreter::invoker<Function,To,To> + { + // the argument list is complete, now call the function + template<typename Args> + static inline + void apply(Function func, token_parser &, Args const & args) + { + fusion::invoke(func,args); + } + }; + + template<typename Function> + typename boost::enable_if< ft::is_nonmember_callable_builtin<Function> >::type + interpreter::register_function(std::string const & name, Function f) + { + // instantiate and store the invoker by name + this->map_invokers[name] = boost::bind( + & invoker<Function>::template apply<fusion::nil>, f,_1,fusion::nil() ); + } + + + void interpreter::parse_input(std::string const & text) const + { + boost::char_separator<char> s(" \t\n\r"); + + token_parser parser + ( boost::make_token_iterator<std::string>(text.begin(), text.end(), s) + , boost::make_token_iterator<std::string>(text.end() , text.end(), s) ); + + while (parser.has_more_tokens()) + { + // read function name + std::string func_name = parser.get<std::string>(); + + // look up function + dictionary::const_iterator entry = map_invokers.find( func_name ); + if (entry == map_invokers.end()) + throw std::runtime_error("unknown function: " + func_name); + + // call the invoker which controls argument parsing + entry->second(parser); + } + } + +} + diff --git a/src/boost/libs/function_types/example/interpreter_example.cpp b/src/boost/libs/function_types/example/interpreter_example.cpp new file mode 100644 index 000000000..9e6118b6e --- /dev/null +++ b/src/boost/libs/function_types/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 <string> +#include <iostream> +#include <stdexcept> + +#include "interpreter.hpp" + +void echo(std::string const & s) +{ + std::cout << s << std::endl; +} + +void add(int a, int b) +{ + std::cout << a + b << std::endl; +} + +void repeat(std::string const & s, int n) +{ + while (--n >= 0) std::cout << s; + std::cout << std::endl; +} + +int main() +{ + example::interpreter interpreter; + + interpreter.register_function("echo", & echo); + interpreter.register_function("add", & add); + interpreter.register_function("repeat", & repeat); + + std::string line = "nonempty"; + while (! line.empty()) + { + std::cout << std::endl << "] ", std::getline(std::cin,line); + + try + { + interpreter.parse_input(line); + } + catch (std::runtime_error &error) + { + std::cerr << error.what() << std::endl; + } + } + + return 0; +} + diff --git a/src/boost/libs/function_types/example/macro_type_args.hpp b/src/boost/libs/function_types/example/macro_type_args.hpp new file mode 100644 index 000000000..350052456 --- /dev/null +++ b/src/boost/libs/function_types/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<int,int>) // ERROR (wrong number of macro arguments) +// +// This problem can be solved by pasing using a parenthesized type +// +// MY_MACRO((std::map<int,int>) // OK +// +// but then there is no way to remove the parentheses in the macro argument +// with the preprocessor. +// We can, however, form a pointer to a function with a single argument (the +// parentheses become part of the type) and extract the argument with template +// metaprogramming: +// +// // Inside the macro definition +// +// typename mpl::front< parameter_types<void(*)a_type> >::type +// +// This code snippet does not read too expressive so we use another macro +// to encapsulate the solution: +// +// // Inside the macro definition +// +// BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(a_type) +// +// As a generalization of this technique we can accept a comma-separated list of +// types. Omitting the mpl::front invocation gives us an MPL-sequence. +// +// +// Limitations +// =========== +// +// - only works for types that are valid function arguments +// +// Acknowledgments +// =============== +// +// Thanks go to Dave Abrahams for letting me know this technique. + +#ifndef BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED +#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT_HPP_INCLUDED + +#include <boost/function_types/parameter_types.hpp> +#include <boost/mpl/front.hpp> + +#define BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type) \ + boost::mpl::front< \ + BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_type) >::type + +#define BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) \ + ::boost::function_types::parameter_types< void(*) parenthesized_types > + + +#endif + diff --git a/src/boost/libs/function_types/example/macro_type_args_example.cpp b/src/boost/libs/function_types/example/macro_type_args_example.cpp new file mode 100644 index 000000000..9f8388381 --- /dev/null +++ b/src/boost/libs/function_types/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 <string> +#include <typeinfo> +#include <iostream> + +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/deref.hpp> + +#include "macro_type_args.hpp" + + +#define TYPE_NAME(parenthesized_type) \ + typeid(BOOST_EXAMPLE_MACRO_TYPE_ARGUMENT(parenthesized_type)).name() + +namespace example +{ + namespace mpl = boost::mpl; + + template<class Curr, class End> + struct mpl_seq_to_string_impl + { + static std::string get(std::string const & prev) + { + typedef typename mpl::next<Curr>::type next_pos; + typedef typename mpl::deref<Curr>::type type; + + return mpl_seq_to_string_impl<next_pos,End>::get( + prev + (prev.empty()? '\0' : ',') + typeid(type).name() ); + } + }; + template<class End> + struct mpl_seq_to_string_impl<End, End> + { + static std::string get(std::string const & prev) + { + return prev; + } + }; + + template<class Seq> + std::string mpl_seq_to_string() + { + typedef typename mpl::begin<Seq>::type begin; + typedef typename mpl::end<Seq>::type end; + + return mpl_seq_to_string_impl<begin, end>::get(""); + } + +} + +#define TYPE_NAMES(parenthesized_types) \ + ::example::mpl_seq_to_string< \ + BOOST_EXAMPLE_MACRO_TYPE_LIST_ARGUMENT(parenthesized_types) >() + +int main() +{ + std::cout << TYPE_NAME((int)) << std::endl; + + std::cout << TYPE_NAMES((int,char)) << std::endl; + std::cout << TYPE_NAMES((int,char,long)) << std::endl; + +} + diff --git a/src/boost/libs/function_types/example/result_of.hpp b/src/boost/libs/function_types/example/result_of.hpp new file mode 100644 index 000000000..7c3341af4 --- /dev/null +++ b/src/boost/libs/function_types/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://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html + +#include <boost/function_types/result_type.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +#include <boost/mpl/eval_if.hpp> +#include <boost/mpl/has_xxx.hpp> + +namespace example +{ + namespace ft = boost::function_types; + namespace mpl = boost::mpl; + + template<typename F> struct result_of; + + namespace detail + { + BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type) + + template<typename F> + struct result_type_member + { + typedef typename F::result_type type; + }; + + template<typename F, typename Desc> + struct result_member_template + { + typedef typename F::template result<Desc>::type type; + }; + +#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564)) + template<typename F> + struct result_member_template< F, F(void) > + { + typedef void type; + }; +#endif + + template<typename F, typename Desc> + struct result_of_impl + : mpl::eval_if + < ft::is_callable_builtin<F> + , ft::result_type<F> + , mpl::eval_if + < has_result_type<F> + , result_type_member<F> + , result_member_template<F,Desc> + > > + { }; + } + + template<typename Desc> + struct result_of + : detail::result_of_impl< typename ft::result_type<Desc>::type, Desc > + { }; +} + diff --git a/src/boost/libs/function_types/example/result_of_example.cpp b/src/boost/libs/function_types/example/result_of_example.cpp new file mode 100644 index 000000000..a8fe2d239 --- /dev/null +++ b/src/boost/libs/function_types/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 <utility> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> + +struct int_result_type { typedef int result_type; }; + +struct int_result_of +{ + template<typename F> struct result { typedef int type; }; +}; + +struct int_result_type_and_float_result_of +{ + typedef int result_type; + template<typename F> struct result { typedef float type; }; +}; + +struct X {}; + +int main() +{ + using namespace boost; + namespace e = example; + + typedef int (*func_ptr)(float, double); + typedef int (&func_ref)(float, double); + typedef int (X::*mem_func_ptr)(float); + typedef int (X::*mem_func_ptr_c)(float) const; + typedef int (X::*mem_func_ptr_v)(float) volatile; + typedef int (X::*mem_func_ptr_cv)(float) const volatile; + + BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_type(float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_of(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_of(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<const int_result_of(double)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<volatile int_result_of(void)>::type, void>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<int_result_type_and_float_result_of(char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<func_ptr(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<func_ref(char, float)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_c(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_v(X,char)>::type, int>::value)); + BOOST_STATIC_ASSERT((is_same<e::result_of<mem_func_ptr_cv(X,char)>::type, int>::value)); + return 0; +} diff --git a/src/boost/libs/function_types/index.html b/src/boost/libs/function_types/index.html new file mode 100644 index 000000000..ee4ce6e07 --- /dev/null +++ b/src/boost/libs/function_types/index.html @@ -0,0 +1,14 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html"> + </head> + <body> + <p>Automatic redirection failed, please go to + <a href="doc/html/index.html">doc/html/index.html</a>.</p> + <p>Copyright Tobias Schwinger 2005-2007</p> + <p>Distributed under the Boost Software License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt"> + LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>).</p> + </body> +</html> + diff --git a/src/boost/libs/function_types/meta/libraries.json b/src/boost/libs/function_types/meta/libraries.json new file mode 100644 index 000000000..44b499eae --- /dev/null +++ b/src/boost/libs/function_types/meta/libraries.json @@ -0,0 +1,15 @@ +{ + "key": "function_types", + "name": "Function Types", + "authors": [ + "Tobias Schwinger" + ], + "description": "Boost.FunctionTypes provides functionality to classify, decompose and synthesize function, function pointer, function reference and pointer to member types.", + "category": [ + "Generic", + "Metaprogramming" + ], + "maintainers": [ + "Tobias Schwinger <tschwinger -at- isonews2.com>" + ] +} diff --git a/src/boost/libs/function_types/test/Jamfile b/src/boost/libs/function_types/test/Jamfile new file mode 100644 index 000000000..e652c466b --- /dev/null +++ b/src/boost/libs/function_types/test/Jamfile @@ -0,0 +1,89 @@ + +# (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 : <address-model>64:<build>no ] + [ compile custom_ccs/nonmember_ccs_exact.cpp : <address-model>64:<build>no ] + [ compile custom_ccs/member_ccs.cpp : <address-model>64:<build>no ] + [ compile custom_ccs/member_ccs_exact.cpp : <address-model>64:<build>no ] + + # Property tag + + [ compile custom_ccs/property_tag.cpp ] + + # Code from the examples + + [ compile ../example/interpreter_example.cpp ] + [ compile ../example/result_of_example.cpp ] + [ compile ../example/interface_example.cpp ] + [ compile ../example/fast_mem_fn_example.cpp + # needed for Boost.PP file iteration with some compilers + : <include>../example + ] + [ compile ../example/macro_type_args_example.cpp ] + ; +} + + diff --git a/src/boost/libs/function_types/test/classification/is_callable_builtin.cpp b/src/boost/libs/function_types/test/classification/is_callable_builtin.cpp new file mode 100644 index 000000000..d65f6f363 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func_ref > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< int[1] > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_cv_function.cpp b/src/boost/libs/function_types/test/classification/is_cv_function.cpp new file mode 100644 index 000000000..176300c90 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_function.hpp> + +namespace ft = boost::function_types; + +template<typename C, typename T> +void test_non_cv(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::non_const > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::non_volatile > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::tag<ft::non_const,ft::non_volatile> > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::const_qualified > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::volatile_qualified > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::tag<ft::const_qualified,ft::volatile_qualified> > + )); +} + +template<typename C, typename T> +void test_c_non_v(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::const_qualified > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::non_volatile > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::tag<ft::const_qualified,ft::non_volatile> > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::non_const > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::volatile_qualified > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::tag<ft::non_const,ft::volatile_qualified> > + )); +} + +template<typename C, typename T> +void test_v_non_c(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::non_const > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::volatile_qualified > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::tag<ft::non_const,ft::volatile_qualified> > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::const_qualified > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::non_volatile > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::tag<ft::const_qualified,ft::non_volatile> > + )); +} + +template<typename C, typename T> +void test_cv(T C::*) +{ + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::const_qualified > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::volatile_qualified > + )); + + BOOST_MPL_ASSERT(( + ft::is_function<T, ft::tag<ft::const_qualified,ft::volatile_qualified> > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::non_const > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::non_volatile > + )); + + BOOST_MPL_ASSERT_NOT(( + ft::is_function<T, ft::tag<ft::non_const,ft::non_volatile> > + )); +} + + +struct C +{ + void non_cv(int) { } + void c_non_v(int) const { } + void v_non_c(int) volatile { } + void cv(int) const volatile { } +}; + +void instanitate() +{ + test_non_cv(& C::non_cv); + test_c_non_v(& C::c_non_v); + test_v_non_c(& C::v_non_c); + test_cv(& C::cv); +} + diff --git a/src/boost/libs/function_types/test/classification/is_cv_mem_func_ptr.cpp b/src/boost/libs/function_types/test/classification/is_cv_mem_func_ptr.cpp new file mode 100644 index 000000000..0b75c43d5 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_member_function_pointer.hpp> + +namespace ft = boost::function_types; + +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; + + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_ptr, ft::non_const > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_ptr, ft::non_volatile > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_ptr, + ft::tag<ft::non_const, ft::non_volatile> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, ft::const_qualified > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, ft::volatile_qualified > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, + ft::tag<ft::const_qualified, ft::volatile_qualified> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, + ft::tag<ft::non_const, ft::volatile_qualified> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr, + ft::tag<ft::const_qualified, ft::non_volatile> > +)); + +// + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< c_mem_func_ptr, ft::const_qualified > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< c_mem_func_ptr, ft::non_volatile > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< c_mem_func_ptr, ft::non_const > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< c_mem_func_ptr, ft::volatile_qualified > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< c_mem_func_ptr, + ft::tag<ft::const_qualified, ft::non_volatile> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< c_mem_func_ptr, + ft::tag<ft::non_const, ft::volatile_qualified> > +)); + +// + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< v_mem_func_ptr, ft::volatile_qualified > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< v_mem_func_ptr, ft::non_const > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< v_mem_func_ptr, ft::non_volatile > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< v_mem_func_ptr, ft::const_qualified > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< v_mem_func_ptr, + ft::tag<ft::non_const, ft::volatile_qualified> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< v_mem_func_ptr, + ft::tag<ft::const_qualified, ft::non_volatile> > +)); + +// + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< cv_mem_func_ptr, ft::const_qualified > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< cv_mem_func_ptr, ft::volatile_qualified > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, ft::non_const > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, ft::non_volatile > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag<ft::non_const, ft::non_volatile> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag<ft::const_qualified, ft::non_volatile> > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag<ft::non_const, ft::volatile_qualified> > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< cv_mem_func_ptr, + ft::tag<ft::const_qualified, ft::volatile_qualified> > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_cv_pointer.cpp b/src/boost/libs/function_types/test/classification/is_cv_pointer.cpp new file mode 100644 index 000000000..383052ee7 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_function_pointer.hpp> +#include <boost/function_types/is_member_function_pointer.hpp> + +namespace ft = boost::function_types; + +typedef void(* const func_c_ptr)(); +typedef void(* volatile func_v_ptr)(); +typedef void(* const volatile func_cv_ptr)(); +class C; +typedef void(C::* const mem_func_c_ptr)(); +typedef void(C::* volatile mem_func_v_ptr)(); +typedef void(C::* const volatile mem_func_cv_ptr)(); + +// note: the pointer has cv-qualifiers, not the function - non_cv tag must match + +BOOST_MPL_ASSERT(( + ft::is_function_pointer< func_c_ptr, ft::non_cv > +)); + +BOOST_MPL_ASSERT(( + ft::is_function_pointer< func_v_ptr, ft::non_cv > +)); + +BOOST_MPL_ASSERT(( + ft::is_function_pointer< func_cv_ptr, ft::non_cv > +)); + + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_c_ptr, ft::non_cv > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_v_ptr, ft::non_cv > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_cv_ptr, ft::non_cv > +)); + + diff --git a/src/boost/libs/function_types/test/classification/is_function.cpp b/src/boost/libs/function_types/test/classification/is_function.cpp new file mode 100644 index 000000000..9c6a35748 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_function.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; + + +BOOST_MPL_ASSERT(( + ft::is_function< func > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< func_ref > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function< int[1] > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_function_pointer.cpp b/src/boost/libs/function_types/test/classification/is_function_pointer.cpp new file mode 100644 index 000000000..54ef29fe1 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_function_pointer.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; + + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< func > +)); + +BOOST_MPL_ASSERT(( + ft::is_function_pointer< func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< func_ref > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_pointer< int[1] > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_function_reference.cpp b/src/boost/libs/function_types/test/classification/is_function_reference.cpp new file mode 100644 index 000000000..2f8f006fd --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_function_reference.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; + + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< func > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_function_reference< func_ref > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_function_reference< int[1] > +)); + + diff --git a/src/boost/libs/function_types/test/classification/is_member_function_pointer.cpp b/src/boost/libs/function_types/test/classification/is_member_function_pointer.cpp new file mode 100644 index 000000000..0548c37f7 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_member_function_pointer.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; +typedef int C::*mem_ptr; + + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< func > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< func_ref > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_function_pointer< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< mem_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_function_pointer< int[1] > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_member_object_pointer.cpp b/src/boost/libs/function_types/test/classification/is_member_object_pointer.cpp new file mode 100644 index 000000000..840832714 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_member_object_pointer.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; +typedef int C::*mem_ptr; + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< func > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< func_ref > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_object_pointer< mem_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< mem_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_object_pointer< int[1] > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_member_pointer.cpp b/src/boost/libs/function_types/test/classification/is_member_pointer.cpp new file mode 100644 index 000000000..113902737 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_member_pointer.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; +typedef int C::*mem_ptr; + + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< func > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< func_ref > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_pointer< mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_pointer< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_pointer< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_pointer< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_member_pointer< mem_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< mem_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_member_pointer< int& > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_nonmember_callable_builtin.cpp b/src/boost/libs/function_types/test/classification/is_nonmember_callable_builtin.cpp new file mode 100644 index 000000000..902d6ee3b --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_nonmember_callable_builtin.hpp> + +namespace ft = boost::function_types; + +typedef void func(); +typedef void (*func_ptr)(); +typedef void (&func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)() const; +typedef void (C::*v_mem_func_ptr)() volatile; +typedef void (C::*cv_mem_func_ptr)() const volatile; + + +BOOST_MPL_ASSERT(( + ft::is_nonmember_callable_builtin< func > +)); + +BOOST_MPL_ASSERT(( + ft::is_nonmember_callable_builtin< func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_nonmember_callable_builtin< func_ref > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< C > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< int > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< int* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< int** > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< int& > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< int[] > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_nonmember_callable_builtin< int[1] > +)); + diff --git a/src/boost/libs/function_types/test/classification/is_variadic.cpp b/src/boost/libs/function_types/test/classification/is_variadic.cpp new file mode 100644 index 000000000..964ea8c56 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +namespace ft = boost::function_types; + +typedef void func(...); +typedef void nv_func(); +typedef void (*func_ptr)(...); +typedef void (*nv_func_ptr)(); +typedef void (&func_ref)(...); +typedef void (&nv_func_ref)(); +class C; +typedef void (C::*mem_func_ptr)(...); +typedef void (C::*nv_mem_func_ptr)(); +typedef void (C::*c_mem_func_ptr)(...) const; +typedef void (C::*v_mem_func_ptr)(...) volatile; +typedef void (C::*cv_mem_func_ptr)(...) const volatile; +typedef int C::* mem_ptr; + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func, ft::variadic > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< func, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< nv_func > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< nv_func, ft::variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< nv_func, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func_ptr, ft::variadic> +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< func_ptr, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< nv_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< nv_func_ptr, ft::variadic> +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< nv_func_ptr, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< func_ref > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< mem_func_ptr, ft::variadic > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< mem_func_ptr, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< nv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< nv_mem_func_ptr, ft::variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< nv_mem_func_ptr, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< c_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< v_mem_func_ptr > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< cv_mem_func_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< mem_func_ptr* > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< C, ft::variadic > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< C, ft::non_variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< mem_ptr > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< mem_ptr, ft::variadic > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< mem_ptr, ft::non_variadic > +)); + diff --git a/src/boost/libs/function_types/test/custom_ccs/member_ccs.cpp b/src/boost/libs/function_types/test/custom_ccs/member_ccs.cpp new file mode 100644 index 000000000..11f939268 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/function_types/member_function_pointer.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +#ifndef BOOST_FT_CC_STDCALL +# error "test not supported with this compiler/platform" +#endif + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +typedef ft::stdcall_cc cc; + +class C; + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer<mpl::vector<int, C &>, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer<mpl::vector<int, C const &>, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer<mpl::vector<int, C volatile &>, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::member_function_pointer<mpl::vector<int, C const volatile &>, cc>::type + > +)); + diff --git a/src/boost/libs/function_types/test/custom_ccs/member_ccs_exact.cpp b/src/boost/libs/function_types/test/custom_ccs/member_ccs_exact.cpp new file mode 100644 index 000000000..413b1334a --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/function_types/member_function_pointer.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +#ifndef BOOST_FT_CC_STDCALL +# error "test not supported with this compiler/platform" +#endif + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +typedef ft::stdcall_cc cc; +typedef ft::default_cc dc; + +class C; + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &>, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const &>, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C volatile &>, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const volatile &>, cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &> >::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &>, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const &>, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C volatile &>, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C const volatile &>, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &> >::type, cc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::member_function_pointer<mpl::vector<int, C &>, cc>::type, dc > +)); + diff --git a/src/boost/libs/function_types/test/custom_ccs/nonmember_ccs.cpp b/src/boost/libs/function_types/test/custom_ccs/nonmember_ccs.cpp new file mode 100644 index 000000000..81681ff02 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/function_types/function_type.hpp> +#include <boost/function_types/function_pointer.hpp> +#include <boost/function_types/function_reference.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +#ifndef BOOST_FT_CC_STDCALL +# error "test not supported with this compiler/platform" +#endif + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +typedef ft::stdcall_cc cc; + + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::function_type<mpl::vector<void,int>, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::function_pointer<mpl::vector<void,int>, cc>::type + > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< + ft::function_reference<mpl::vector<void,int>, cc>::type + > +)); + diff --git a/src/boost/libs/function_types/test/custom_ccs/nonmember_ccs_exact.cpp b/src/boost/libs/function_types/test/custom_ccs/nonmember_ccs_exact.cpp new file mode 100644 index 000000000..d6db30024 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/function_types/function_type.hpp> +#include <boost/function_types/function_pointer.hpp> +#include <boost/function_types/function_reference.hpp> +#include <boost/function_types/is_callable_builtin.hpp> + +#ifndef BOOST_FT_CC_STDCALL +# error "test not supported with this compiler/platform" +#endif + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +typedef ft::stdcall_cc cc; +typedef ft::default_cc dc; + + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_type<mpl::vector<void>,cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_pointer<mpl::vector<void>,cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_reference<mpl::vector<void>,cc>::type, cc > +)); + +BOOST_MPL_ASSERT(( + ft::is_callable_builtin< ft::function_pointer<mpl::vector<void> >::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_type<mpl::vector<void>, cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_pointer<mpl::vector<void>,cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_reference<mpl::vector<void>,cc>::type, dc > +)); + +BOOST_MPL_ASSERT_NOT(( + ft::is_callable_builtin< ft::function_pointer<mpl::vector<void> >::type, cc > +)); + + + diff --git a/src/boost/libs/function_types/test/custom_ccs/property_tag.cpp b/src/boost/libs/function_types/test/custom_ccs/property_tag.cpp new file mode 100644 index 000000000..00d241942 --- /dev/null +++ b/src/boost/libs/function_types/test/custom_ccs/property_tag.cpp @@ -0,0 +1,64 @@ + +// (C) Copyright Edward Diener 2019 +// Use, modification and distribution are 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). + +//------------------------------------------------------------------------------ + +#include <boost/mpl/assert.hpp> +#include <boost/function_types/property_tags.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +typedef ft::tag<ft::variadic,ft::non_volatile,ft::non_const,ft::default_cc> tag1; +typedef ft::tag<ft::const_non_volatile,ft::const_qualified> tag2; +typedef ft::tag<ft::cv_qualified,ft::variadic> tag3; +typedef ft::null_tag tag4; +typedef ft::tag<ft::variadic,ft::volatile_non_const> tag5; +typedef ft::tag<ft::volatile_qualified,ft::non_const,ft::variadic> tag6; +typedef ft::tag<ft::non_variadic,ft::const_non_volatile,ft::default_cc> tag7; +typedef ft::tag<ft::non_cv,ft::default_cc> tag8; + +BOOST_MPL_ASSERT((ft::has_property_tag<tag1, ft::variadic>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag2, ft::const_qualified>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag3, ft::cv_qualified>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag4, ft::null_tag>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag5, ft::volatile_qualified>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag6, ft::volatile_qualified>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag7, ft::const_qualified>)); +BOOST_MPL_ASSERT((ft::has_property_tag<tag8, ft::default_cc>)); + +BOOST_MPL_ASSERT((ft::has_variadic_property_tag<tag1>)); +BOOST_MPL_ASSERT((ft::has_variadic_property_tag<tag3>)); +BOOST_MPL_ASSERT((ft::has_variadic_property_tag<tag5>)); +BOOST_MPL_ASSERT((ft::has_variadic_property_tag<tag6>)); +BOOST_MPL_ASSERT((ft::has_default_cc_property_tag<tag1>)); +BOOST_MPL_ASSERT((ft::has_default_cc_property_tag<tag7>)); +BOOST_MPL_ASSERT((ft::has_default_cc_property_tag<tag8>)); +BOOST_MPL_ASSERT((ft::has_const_property_tag<tag2>)); +BOOST_MPL_ASSERT((ft::has_const_property_tag<tag3>)); +BOOST_MPL_ASSERT((ft::has_const_property_tag<tag7>)); +BOOST_MPL_ASSERT((ft::has_volatile_property_tag<tag3>)); +BOOST_MPL_ASSERT((ft::has_volatile_property_tag<tag5>)); +BOOST_MPL_ASSERT((ft::has_volatile_property_tag<tag6>)); +BOOST_MPL_ASSERT((ft::has_cv_property_tag<tag3>)); +BOOST_MPL_ASSERT((ft::has_null_property_tag<tag4>)); + +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag1, ft::const_qualified>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag2, ft::cv_qualified>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag3, ft::null_tag>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag4, ft::volatile_qualified>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag5, ft::const_qualified>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag6, ft::default_cc>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag7, ft::variadic>)); +BOOST_MPL_ASSERT_NOT((ft::has_property_tag<tag8, ft::volatile_qualified>)); + +BOOST_MPL_ASSERT_NOT((ft::has_variadic_property_tag<tag2>)); +BOOST_MPL_ASSERT_NOT((ft::has_default_cc_property_tag<tag6>)); +BOOST_MPL_ASSERT_NOT((ft::has_const_property_tag<tag4>)); +BOOST_MPL_ASSERT_NOT((ft::has_const_property_tag<tag5>)); +BOOST_MPL_ASSERT_NOT((ft::has_volatile_property_tag<tag7>)); +BOOST_MPL_ASSERT_NOT((ft::has_cv_property_tag<tag1>)); +BOOST_MPL_ASSERT_NOT((ft::has_null_property_tag<tag8>)); diff --git a/src/boost/libs/function_types/test/decomposition/class_type_transform.cpp b/src/boost/libs/function_types/test/decomposition/class_type_transform.cpp new file mode 100644 index 000000000..f007a40c7 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/type_traits/is_same.hpp> +#include <boost/type_traits/add_pointer.hpp> + +#include <boost/mpl/assert.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/placeholders.hpp> +#include <boost/mpl/always.hpp> + +#include <boost/function_types/components.hpp> +#include <boost/function_types/parameter_types.hpp> + +using namespace boost; +namespace ft = function_types; +using boost::mpl::placeholders::_; + +class C; +typedef C (C::*mem_func_ptr)(); +class X; + +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::components<mem_func_ptr, add_pointer<_> > + ,1 >::type, C* > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::components<mem_func_ptr, add_pointer< add_pointer<_> > > + ,1 >::type, C** > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::components<mem_func_ptr, mpl::always<X> > + ,1 >::type, X > +)); + +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::parameter_types<mem_func_ptr, add_pointer<_> > + ,0 >::type, C* > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::parameter_types<mem_func_ptr, add_pointer< add_pointer<_> > > + ,0 >::type, C** > +)); +BOOST_MPL_ASSERT(( + is_same< mpl::at_c< + ft::parameter_types<mem_func_ptr, mpl::always<X> > + ,0 >::type, X > +)); + + + + diff --git a/src/boost/libs/function_types/test/decomposition/components.cpp b/src/boost/libs/function_types/test/decomposition/components.cpp new file mode 100644 index 000000000..60cebde3d --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/equal.hpp> + +#include <boost/function_types/components.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +class C; +typedef C func(); +typedef C (*func_ptr)(int); +typedef C (&func_ref)(int,int); +typedef C (C::*mem_func_ptr)(); +typedef C (C::*c_mem_func_ptr)(int) const; +typedef C (C::*v_mem_func_ptr)(int,int) volatile; +typedef C (C::*cv_mem_func_ptr)(int,int,int) const volatile; +typedef int C::* mem_ptr; + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<func>::types, mpl::vector<C> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<func_ptr>::types, mpl::vector<C,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<func_ref>::types, mpl::vector<C,int,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<mem_func_ptr>::types, mpl::vector<C,C &> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<c_mem_func_ptr>::types, mpl::vector<C,C const &,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<v_mem_func_ptr>::types, mpl::vector<C,C volatile &,int,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<cv_mem_func_ptr>::types, mpl::vector<C,C const volatile &,int,int,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::components<mem_ptr>::types, mpl::vector<int &,C&> > +)); + diff --git a/src/boost/libs/function_types/test/decomposition/components_seq.cpp b/src/boost/libs/function_types/test/decomposition/components_seq.cpp new file mode 100644 index 000000000..ad5f5900c --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/type_traits/is_same.hpp> + +#include <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/equal.hpp> + +#include <boost/mpl/front.hpp> +#include <boost/mpl/back.hpp> +#include <boost/mpl/at.hpp> +#include <boost/mpl/begin_end.hpp> +#include <boost/mpl/clear.hpp> +#include <boost/mpl/push_front.hpp> +#include <boost/mpl/pop_front.hpp> +#include <boost/mpl/push_back.hpp> +#include <boost/mpl/pop_back.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/empty.hpp> + +#include <boost/function_types/components.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; +typedef C (C::* mem_func_ptr)(int); +typedef ft::components<mem_func_ptr> c; + + +// front +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::front<c>::type, C > )); + +// back +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::back<c>::type, int > )); + +// at +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c<c,0>::type, C > )); +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c<c,1>::type, C & > )); +BOOST_MPL_ASSERT(( is_same< ::boost::mpl::at_c<c,2>::type, int > )); + +// begin/end +BOOST_MPL_ASSERT(( mpl::equal< c, mpl::vector<C,C &, int> > )); + + +// clear +BOOST_MPL_ASSERT(( mpl::equal< mpl::clear<c>, mpl::vector<> > )); + +// push_front +BOOST_MPL_ASSERT(( mpl::equal< mpl::push_front<c,C>::type, mpl::vector<C,C,C &,int> > )); + +// pop_front +BOOST_MPL_ASSERT(( mpl::equal< mpl::pop_front<c>::type, mpl::vector<C &,int> > )); + +// push_back +BOOST_MPL_ASSERT(( mpl::equal< mpl::push_back<c,C>::type, mpl::vector<C,C &,int,C> > )); + +// pop_back +BOOST_MPL_ASSERT(( mpl::equal< mpl::pop_back<c>::type, mpl::vector<C,C &> > )); + + +// size +BOOST_MPL_ASSERT_RELATION( ::boost::mpl::size<c>::value, ==, 3 ); + +// empty +BOOST_MPL_ASSERT_NOT(( mpl::empty<c> )); +BOOST_MPL_ASSERT(( mpl::empty< mpl::clear<c> > )); + diff --git a/src/boost/libs/function_types/test/decomposition/function_arity.cpp b/src/boost/libs/function_types/test/decomposition/function_arity.cpp new file mode 100644 index 000000000..219c2c6ef --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> + +#include <boost/function_types/function_arity.hpp> + +class C; +typedef C func(); +typedef C (*func_ptr)(int); +typedef C (&func_ref)(int,int); +typedef C (C::*mem_func_ptr)(); +typedef C (C::*c_mem_func_ptr)(int) const; +typedef C (C::*v_mem_func_ptr)(int,int) volatile; +typedef C (C::*cv_mem_func_ptr)(int,int,int) const volatile; +typedef int C::* mem_ptr; + +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<func>::value, ==, 0 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<func_ptr>::value, ==, 1 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<func_ref>::value, ==, 2 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<mem_func_ptr>::value, ==, 1 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<c_mem_func_ptr>::value, ==, 2 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<v_mem_func_ptr>::value, ==, 3 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<cv_mem_func_ptr>::value, ==, 4 ); +BOOST_MPL_ASSERT_RELATION( ::boost::function_types::function_arity<mem_ptr>::value, ==, 1 ); + diff --git a/src/boost/libs/function_types/test/decomposition/function_arity_fail.cpp b/src/boost/libs/function_types/test/decomposition/function_arity_fail.cpp new file mode 100644 index 000000000..39a7c7409 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/function_types/function_arity.hpp> + + +namespace ft = boost::function_types; + +class C; + +typedef ft::function_arity<C>::type error_1; +typedef ft::function_arity<int>::type error_2; +typedef ft::function_arity<void>::type error_3; + diff --git a/src/boost/libs/function_types/test/decomposition/parameter_types.cpp b/src/boost/libs/function_types/test/decomposition/parameter_types.cpp new file mode 100644 index 000000000..5feb1a886 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/mpl/equal.hpp> + +#include <boost/function_types/parameter_types.hpp> + + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +class C; +typedef C func(C); +typedef C (*func_ptr)(C,int); +typedef C (&func_ref)(); +typedef C (C::*mem_func_ptr)(C,int); +typedef C (C::*c_mem_func_ptr)(C,C) const; +typedef C (C::*v_mem_func_ptr)(C) volatile; +typedef C (C::*cv_mem_func_ptr)() const volatile; +typedef C C::*mem_ptr; + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<func>, mpl::vector<C> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<func_ptr>::type, mpl::vector<C,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<func_ref>, mpl::vector<> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<mem_func_ptr>, mpl::vector<C &,C,int> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<c_mem_func_ptr>, mpl::vector<C const &,C,C> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<v_mem_func_ptr>, mpl::vector<C volatile &,C> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<cv_mem_func_ptr>, mpl::vector<C const volatile &> > +)); + +BOOST_MPL_ASSERT(( + mpl::equal< ft::parameter_types<mem_ptr>, mpl::vector<C &> > +)); diff --git a/src/boost/libs/function_types/test/decomposition/parameter_types_fail.cpp b/src/boost/libs/function_types/test/decomposition/parameter_types_fail.cpp new file mode 100644 index 000000000..d23e8911b --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/function_types/parameter_types.hpp> + + +namespace ft = boost::function_types; + +class C; + +typedef ft::parameter_types<C>::type error_1; +typedef ft::parameter_types<char>::type error_2; +typedef ft::parameter_types<void>::type error_3; + diff --git a/src/boost/libs/function_types/test/decomposition/result_type.cpp b/src/boost/libs/function_types/test/decomposition/result_type.cpp new file mode 100644 index 000000000..f55eb854d --- /dev/null +++ b/src/boost/libs/function_types/test/decomposition/result_type.cpp @@ -0,0 +1,98 @@ + +// (C) Copyright Tobias Schwinger +// +// Use modification and distribution are subject to the boost Software License, +// Version 1.0. (See http://www.boost.org/LICENSE_1_0.txt). + +//------------------------------------------------------------------------------ + +#include <boost/mpl/assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/function_types/result_type.hpp> + + +namespace ft = boost::function_types; + +class C; +typedef C func(); +typedef C const c_func(); +typedef C (*func_ptr)(); +typedef C const (*c_func_ptr)(); +typedef C (&func_ref)(); +typedef C const (&c_func_ref)(); +typedef C (C::*mem_func_ptr)(); +typedef C const (C::*c_mem_func_ptr)(); +typedef C (C::*mem_func_ptr_c)() const; +typedef C const (C::*c_mem_func_ptr_c)() const; +typedef C (C::*mem_func_ptr_v)() volatile; +typedef C const (C::*c_mem_func_ptr_v)() volatile; +typedef C (C::*mem_func_ptr_cv)() const volatile; +typedef C const (C::*c_mem_func_ptr_cv)() const volatile; +typedef int C::* mem_ptr; +typedef int const C::* c_mem_ptr; + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<func>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_func>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<func_ptr>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_func_ptr>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<func_ref>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_func_ref>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<mem_func_ptr>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_mem_func_ptr>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<mem_func_ptr_c>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_mem_func_ptr_c>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<mem_func_ptr_v>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_mem_func_ptr_v>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<mem_func_ptr_cv>::type,C> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_mem_func_ptr_cv>::type,C const> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<mem_ptr>::type,int&> +)); + +BOOST_MPL_ASSERT(( + boost::is_same<ft::result_type<c_mem_ptr>::type,int const&> +)); + diff --git a/src/boost/libs/function_types/test/decomposition/result_type_fail.cpp b/src/boost/libs/function_types/test/decomposition/result_type_fail.cpp new file mode 100644 index 000000000..c701e5796 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/function_types/result_type.hpp> + + +namespace ft = boost::function_types; + +class C; + +typedef ft::result_type<C>::type error_1; +typedef ft::result_type<char>::type error_2; +typedef ft::result_type<void>::type error_3; + diff --git a/src/boost/libs/function_types/test/reconfiguration/cc_preprocessing.cpp b/src/boost/libs/function_types/test/reconfiguration/cc_preprocessing.cpp new file mode 100644 index 000000000..889645d14 --- /dev/null +++ b/src/boost/libs/function_types/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/src/boost/libs/function_types/test/reconfiguration/partial_arity_preprocessing.cpp b/src/boost/libs/function_types/test/reconfiguration/partial_arity_preprocessing.cpp new file mode 100644 index 000000000..bd58cf92a --- /dev/null +++ b/src/boost/libs/function_types/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/src/boost/libs/function_types/test/reconfiguration/preprocessing_mode.cpp b/src/boost/libs/function_types/test/reconfiguration/preprocessing_mode.cpp new file mode 100644 index 000000000..d6601c4ec --- /dev/null +++ b/src/boost/libs/function_types/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/src/boost/libs/function_types/test/reconfiguration/simple_test.hpp b/src/boost/libs/function_types/test/reconfiguration/simple_test.hpp new file mode 100644 index 000000000..5b62a0bd5 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/equal.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/function_types/components.hpp> +#include <boost/function_types/function_type.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +class C; +typedef void func(C &); +typedef int (C::* mem_func_ptr)(int); + +typedef ft::components<func> func_components; +typedef ft::components<mem_func_ptr> mfp_components; + +BOOST_MPL_ASSERT(( + mpl::equal< func_components::types, mpl::vector<void,C &> > +)); +BOOST_MPL_ASSERT_RELATION( + ::func_components::function_arity::value, ==, 1 +); + +BOOST_MPL_ASSERT(( + boost::is_same< ft::function_type< mpl::vector<void,C &> >::type, func > +)); + + +BOOST_MPL_ASSERT(( + mpl::equal< mfp_components::types, mpl::vector<int,C &,int> > +)); +BOOST_MPL_ASSERT_RELATION( + ::mfp_components::function_arity::value, ==, 2 +); + +BOOST_MPL_ASSERT(( + boost::is_same< ft::member_function_pointer< mpl::vector<int,C &,int> >::type, mem_func_ptr > +)); + + diff --git a/src/boost/libs/function_types/test/synthesis/cv_function_synthesis.cpp b/src/boost/libs/function_types/test/synthesis/cv_function_synthesis.cpp new file mode 100644 index 000000000..b80e8547e --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/function_types/function_type.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +template<typename C, typename T> +void test_non_cv(T C::*) +{ + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::volatile_qualified> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( + boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::volatile_qualified> >::type + , T + >)); +} + +template<typename C, typename T> +void test_c_non_v(T C::*) +{ + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int> >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::volatile_qualified> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( + boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::volatile_qualified> >::type + , T + >)); +} + +template<typename C, typename T> +void test_v_non_c(T C::*) +{ + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::volatile_qualified> >::type + , T + >)); + + BOOST_MPL_ASSERT(( + boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::volatile_qualified> >::type + , T + >)); +} + +template<typename C, typename T> +void test_cv(T C::*) +{ + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_const >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::non_volatile >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::non_volatile> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::const_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::non_const,ft::volatile_qualified> >::type + , T + >)); + + BOOST_MPL_ASSERT_NOT(( + boost::is_same< + ft::function_type< mpl::vector<void,int>, ft::volatile_qualified >::type + , T + >)); + + BOOST_MPL_ASSERT(( boost::is_same< + ft::function_type< mpl::vector<void,int>, + ft::tag<ft::const_qualified,ft::volatile_qualified> >::type + , T + >)); +} + + +struct C +{ + void non_cv(int) { } + void c_non_v(int) const { } + void v_non_c(int) volatile { } + void cv(int) const volatile { } +}; + +void instanitate() +{ + test_non_cv(& C::non_cv); + test_c_non_v(& C::c_non_v); + test_v_non_c(& C::v_non_c); + test_cv(& C::cv); +} + diff --git a/src/boost/libs/function_types/test/synthesis/function_pointer.cpp b/src/boost/libs/function_types/test/synthesis/function_pointer.cpp new file mode 100644 index 000000000..115093487 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +using boost::is_same; + +typedef int (* expected)(int,int); + +BOOST_MPL_ASSERT(( + is_same< ft::function_pointer< mpl::vector<int,int,int> >::type, expected > +)); + diff --git a/src/boost/libs/function_types/test/synthesis/function_reference.cpp b/src/boost/libs/function_types/test/synthesis/function_reference.cpp new file mode 100644 index 000000000..92fa714e3 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/function_reference.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; + +using boost::is_same; + +typedef int (& expected)(int); + +BOOST_MPL_ASSERT(( + is_same< ft::function_reference< mpl::vector<int,int> >::type, expected > +)); + diff --git a/src/boost/libs/function_types/test/synthesis/function_type.cpp b/src/boost/libs/function_types/test/synthesis/function_type.cpp new file mode 100644 index 000000000..bb08ce7f2 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/function_type.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +typedef int expected(int,int); + +BOOST_MPL_ASSERT(( + is_same< ft::function_type< mpl::vector<int,int,int> >::type, expected > +)); + diff --git a/src/boost/libs/function_types/test/synthesis/mem_func_ptr_cv1.cpp b/src/boost/libs/function_types/test/synthesis/mem_func_ptr_cv1.cpp new file mode 100644 index 000000000..b1f70beee --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; + +typedef int (C::* expected1)(int); +typedef int (C::* expected2)(int) const; +typedef int (C::* expected3)(int) volatile; +typedef int (C::* expected4)(int) const volatile; + +// implicitly specified cv qualification + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int> >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const,int> >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector<int,C volatile,int> >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector<int,C const volatile,int> >::type + , expected4 > +)); + +// implicit & explicit/overrides + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector<int,C const volatile,int> + , ft::tag<ft::non_const, ft::non_volatile> >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C volatile,int>, + ft::tag<ft::const_qualified, ft::non_volatile> >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const,int>, + ft::tag<ft::non_const, ft::volatile_qualified> >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const,int>, + ft::tag<ft::const_qualified, ft::volatile_qualified> >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C volatile,int>, + ft::tag<ft::const_qualified, ft::volatile_qualified> >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C volatile,int> + , ft::const_qualified >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const,int> + , ft::volatile_qualified >::type + , expected4 > +)); + + diff --git a/src/boost/libs/function_types/test/synthesis/mem_func_ptr_cv2.cpp b/src/boost/libs/function_types/test/synthesis/mem_func_ptr_cv2.cpp new file mode 100644 index 000000000..007efa038 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; + +typedef int (C::* expected1)(int); +typedef int (C::* expected2)(int) const; +typedef int (C::* expected3)(int) volatile; +typedef int (C::* expected4)(int) const volatile; + +// implicitly specified cv qualification + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C &,int> >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const &,int> >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector<int,C volatile &,int> >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector<int,C const volatile &,int> >::type + , expected4 > +)); + +// implicit & explicit/overrides + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< + mpl::vector<int,C const volatile &,int> + , ft::tag<ft::non_const, ft::non_volatile> >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C volatile &,int>, + ft::tag<ft::const_qualified, ft::non_volatile> >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const &,int>, + ft::tag<ft::non_const, ft::volatile_qualified> >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const &,int>, + ft::tag<ft::const_qualified, ft::volatile_qualified> >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C volatile &,int>, + ft::tag<ft::const_qualified, ft::volatile_qualified> >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C volatile &,int> + , ft::const_qualified >::type + , expected4 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C const &,int> + , ft::volatile_qualified >::type + , expected4 > +)); + + diff --git a/src/boost/libs/function_types/test/synthesis/mem_func_ptr_cv_ptr_to_this.cpp b/src/boost/libs/function_types/test/synthesis/mem_func_ptr_cv_ptr_to_this.cpp new file mode 100644 index 000000000..1b6d906fe --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; +typedef int (C::* expected)(); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C * const> >::type + , expected > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C * volatile> >::type + , expected > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C * const volatile> >::type + , expected > +)); + + + diff --git a/src/boost/libs/function_types/test/synthesis/member_function_pointer.cpp b/src/boost/libs/function_types/test/synthesis/member_function_pointer.cpp new file mode 100644 index 000000000..6234c474f --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; + +typedef int (C::* expected1)(int); +typedef int (C::* expected2)(int) const; +typedef int (C::* expected3)(int) volatile; +typedef int (C::* expected4)(int) const volatile; + + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int> >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int>, + ft::tag<ft::non_const, ft::non_volatile> >::type + , expected1 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int> + , ft::const_qualified >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int>, + ft::tag<ft::const_qualified, ft::non_volatile> >::type + , expected2 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int> + , ft::volatile_qualified >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int>, + ft::tag<ft::non_const, ft::volatile_qualified> >::type + , expected3 > +)); + +BOOST_MPL_ASSERT(( + is_same< ft::member_function_pointer< mpl::vector<int,C,int>, + ft::tag<ft::const_qualified, ft::volatile_qualified> >::type + , expected4 > +)); + diff --git a/src/boost/libs/function_types/test/synthesis/member_object_pointer.cpp b/src/boost/libs/function_types/test/synthesis/member_object_pointer.cpp new file mode 100644 index 000000000..65af74121 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/function_types/member_object_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; + +typedef int C::* expected; + + +BOOST_MPL_ASSERT(( + is_same< ft::member_object_pointer< mpl::vector<int,C> >::type + , expected > +)); + diff --git a/src/boost/libs/function_types/test/synthesis/transformation.cpp b/src/boost/libs/function_types/test/synthesis/transformation.cpp new file mode 100644 index 000000000..38856476a --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/function_types/function_type.hpp> +#include <boost/function_types/function_pointer.hpp> +#include <boost/function_types/function_reference.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; + +typedef C func1(C &); +typedef C (*func_ptr1)(C &); +typedef C (&func_ref1)(C &); +typedef C (C::*mem_func_ptr1)(); + +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<func1>::type > )); +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<func_ptr1>::type > )); +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<func_ref1>::type > )); +BOOST_MPL_ASSERT(( is_same< func1, ft::function_type<mem_func_ptr1>::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<func1>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<func_ptr1>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<func_ref1>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr1, ft::function_pointer<mem_func_ptr1>::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<func1>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<func_ptr1>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<func_ref1>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref1, ft::function_reference<mem_func_ptr1>::type > )); + +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<func1>::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<func_ptr1>::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<func_ref1>::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr1, ft::member_function_pointer<mem_func_ptr1>::type > )); + + +typedef C func2(C const &); +typedef C (*func_ptr2)(C const &); +typedef C (&func_ref2)(C const &); +typedef C (C::*mem_func_ptr2)() const; + +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<func2>::type > )); +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<func_ptr2>::type > )); +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<func_ref2>::type > )); +BOOST_MPL_ASSERT(( is_same< func2, ft::function_type<mem_func_ptr2>::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<func2>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<func_ptr2>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<func_ref2>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ptr2, ft::function_pointer<mem_func_ptr2>::type > )); + +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<func2>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<func_ptr2>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<func_ref2>::type > )); +BOOST_MPL_ASSERT(( is_same< func_ref2, ft::function_reference<mem_func_ptr2>::type > )); + +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<func2>::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<func_ptr2>::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<func_ref2>::type > )); +BOOST_MPL_ASSERT(( is_same< mem_func_ptr2, ft::member_function_pointer<mem_func_ptr2>::type > )); + + + diff --git a/src/boost/libs/function_types/test/synthesis/variadic_function_synthesis.cpp b/src/boost/libs/function_types/test/synthesis/variadic_function_synthesis.cpp new file mode 100644 index 000000000..d35b31911 --- /dev/null +++ b/src/boost/libs/function_types/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 <boost/mpl/assert.hpp> +#include <boost/mpl/vector.hpp> +#include <boost/type_traits/is_same.hpp> + +#include <boost/function_types/function_type.hpp> +#include <boost/function_types/function_pointer.hpp> +#include <boost/function_types/function_reference.hpp> +#include <boost/function_types/member_function_pointer.hpp> + +namespace ft = boost::function_types; +namespace mpl = boost::mpl; +using boost::is_same; + +class C; +typedef int expected_v_1(...); +typedef int expected_nv_1(); +typedef int (C::*expected_v_2)(...); +typedef int (C::*expected_nv_2)(); + +BOOST_MPL_ASSERT(( is_same< + ft::function_type<mpl::vector<int>, ft::variadic>::type, expected_v_1 +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_type<mpl::vector<int>, ft::non_variadic>::type, expected_nv_1 +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_pointer<mpl::vector<int>, ft::variadic>::type, expected_v_1 * +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_pointer<mpl::vector<int>, ft::non_variadic>::type + , expected_nv_1 * +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_reference<mpl::vector<int>, ft::variadic>::type, expected_v_1 & +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::function_reference<mpl::vector<int>, ft::non_variadic>::type + , expected_nv_1 & +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::member_function_pointer<mpl::vector<int,C>, ft::variadic>::type + , expected_v_2 +> )); + +BOOST_MPL_ASSERT(( is_same< + ft::member_function_pointer<mpl::vector<int,C>, ft::non_variadic>::type + , expected_nv_2 +> )); + |