$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r80601 - in sandbox/type_erasure: boost/type_erasure boost/type_erasure/detail libs/type_erasure/test
From: steven_at_[hidden]
Date: 2012-09-19 18:46:37
Author: steven_watanabe
Date: 2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
New Revision: 80601
URL: http://svn.boost.org/trac/boost/changeset/80601
Log:
Implement BOOST_TYPE_ERASURE_FREE matching BOOST_TYPE_ERASURE_MEMBER.
Added:
   sandbox/type_erasure/boost/type_erasure/detail/macro.hpp   (contents, props changed)
   sandbox/type_erasure/boost/type_erasure/free.hpp   (contents, props changed)
   sandbox/type_erasure/libs/type_erasure/test/test_free.cpp   (contents, props changed)
Text files modified: 
   sandbox/type_erasure/boost/type_erasure/member.hpp      |    54 +++++++++++---------------------------- 
   sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam |     1                                         
   2 files changed, 16 insertions(+), 39 deletions(-)
Added: sandbox/type_erasure/boost/type_erasure/detail/macro.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/detail/macro.hpp	2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -0,0 +1,47 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_MACRO_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_MACRO_HPP_INCLUDED
+
+#include <boost/preprocessor/dec.hpp>
+#include <boost/preprocessor/if.hpp>
+#include <boost/preprocessor/comparison/not_equal.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/seq/for_each.hpp>
+#include <boost/preprocessor/seq/pop_back.hpp>
+#include <boost/preprocessor/seq/size.hpp>
+#include <boost/preprocessor/tuple/eat.hpp>
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F(z, data, x) \
+    namespace x {
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I(seq)\
+    BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F, ~, BOOST_PP_SEQ_POP_BACK(seq))
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE(seq)\
+    BOOST_PP_IF(BOOST_PP_NOT_EQUAL(BOOST_PP_SEQ_SIZE(seq), 1), BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I, BOOST_PP_TUPLE_EAT(1))(seq)
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(seq) \
+    BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), } BOOST_PP_TUPLE_EAT(3), ~)
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_QUALIFIED_NAME_F(z, data, x)\
+    ::x
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq) \
+    BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_QUALIFIED_NAME_F, ~, seq)
+
+#endif
Added: sandbox/type_erasure/boost/type_erasure/free.hpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/boost/type_erasure/free.hpp	2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -0,0 +1,157 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#ifndef BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
+#define BOOST_TYPE_ERASURE_FREE_HPP_INCLUDED
+
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_cv.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/next.hpp>
+#include <boost/type_erasure/detail/macro.hpp>
+#include <boost/type_erasure/config.hpp>
+#include <boost/type_erasure/derived.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/is_placeholder.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
+
+namespace boost {
+namespace type_erasure {
+namespace detail {
+
+template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_TYPE_ERASURE_MAX_ARITY, class T, void)>
+struct first_placeholder {
+    typedef typename ::boost::mpl::eval_if<is_placeholder<T0>,
+        ::boost::mpl::identity<T0>,
+        first_placeholder<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_TYPE_ERASURE_MAX_ARITY, T)>
+    >::type type;
+};
+
+template<>
+struct first_placeholder<> {};
+
+template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_TYPE_ERASURE_MAX_ARITY, class T, void)>
+struct first_placeholder_index :
+    ::boost::mpl::eval_if<is_placeholder<T0>,
+        ::boost::mpl::int_<0>,
+        ::boost::mpl::next<first_placeholder<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_TYPE_ERASURE_MAX_ARITY, T)> >
+    >::type
+{};
+
+}
+}
+}
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(seq, N) \
+    BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, T))>
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE(z, n, data) \
+    typename ::boost::remove_cv<typename ::boost::remove_reference<BOOST_PP_CAT(T, n)>::type>::type
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_PARAM_TYPE(z, n, data)                      \
+    typename ::boost::mpl::eval_if_c<(_boost_type_erasure_free_p_idx::value == n), \
+        ::boost::type_erasure::derived<Base>,                               \
+        ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(T, n)>         \
+    >::type BOOST_PP_CAT(t, n)
+
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_II(qual_name, concept_name, function_name, N)  \
+    BOOST_TYPE_ERASURE_OPEN_NAMESPACE(qual_name)                        \
+                                                                        \
+    template<class Sig>                                                 \
+    struct concept_name;                                                \
+                                                                        \
+    template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T)>         \
+    struct concept_name<R(BOOST_PP_ENUM_PARAMS(N, T))> {                \
+        static R apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t))            \
+        { return function_name(BOOST_PP_ENUM_PARAMS(N, t)); }           \
+    };                                                                  \
+                                                                        \
+    template<BOOST_PP_ENUM_PARAMS(N, class T)>                          \
+    struct concept_name<void(BOOST_PP_ENUM_PARAMS(N, T))> {             \
+        static void apply(BOOST_PP_ENUM_BINARY_PARAMS(N, T, t))         \
+        { function_name(BOOST_PP_ENUM_PARAMS(N, t)); }                  \
+    };                                                                  \
+                                                                        \
+    BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(qual_name)                       \
+                                                                        \
+    namespace boost {                                                   \
+    namespace type_erasure {                                            \
+                                                                        \
+    template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class T), class Base> \
+    struct concept_interface<                                           \
+        BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N),             \
+        Base,                                                           \
+        typename ::boost::type_erasure::detail::first_placeholder<      \
+            BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE, ~)>::type  \
+    > : Base {                                                          \
+        typedef typename ::boost::type_erasure::detail::first_placeholder_index<    \
+            BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_UNQUALIFIED_PARAM_TYPE, ~)>::type  \
+            _boost_type_erasure_free_p_idx;                             \
+        friend typename ::boost::type_erasure::rebind_any<Base, R>::type function_name(  \
+            BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_FREE_PARAM_TYPE, ~))    \
+        {                                                               \
+            return ::boost::type_erasure::call(                         \
+                BOOST_TYPE_ERASURE_FREE_QUALIFIED_ID(qual_name, N)()    \
+                BOOST_PP_ENUM_TRAILING_PARAMS(N, t));                   \
+        }                                                               \
+    };                                                                  \
+                                                                        \
+    }                                                                   \
+    }
+    
+/** INTERNAL ONLY */
+#define BOOST_TYPE_ERASURE_FREE_I(namespace_name, concept_name, function_name, N)\
+    BOOST_TYPE_ERASURE_FREE_II(namespace_name, concept_name, function_name, N)
+
+/**
+ * \brief Defines a primitive concept for a free function.
+ *
+ * \param qualified_name should be a preprocessor sequence
+ * of the form (namespace1)(namespace2)...(concept_name).
+ * \param function_name is the name of the function.
+ * \param N is the number of arguments of the function.
+ *
+ * The declaration of the concept is
+ * \code
+ * template<class Sig>
+ * struct ::namespace1::namespace2::...::concept_name;
+ * \endcode
+ * where Sig is a function type giving the
+ * signature of the member function.
+ *
+ * This macro can only be used in the global namespace.
+ *
+ * Example:
+ *
+ * \code
+ * BOOST_TYPE_ERASURE_FREE((boost)(has_to_string), to_string, 1)
+ * \endcode
+ */
+#define BOOST_TYPE_ERASURE_FREE(qualified_name, function_name, N)                           \
+    BOOST_TYPE_ERASURE_FREE_I(                                                              \
+        qualified_name,                                                                     \
+        BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(qualified_name)), qualified_name), \
+        function_name,                                                                             \
+        N)
+
+#endif
Modified: sandbox/type_erasure/boost/type_erasure/member.hpp
==============================================================================
--- sandbox/type_erasure/boost/type_erasure/member.hpp	(original)
+++ sandbox/type_erasure/boost/type_erasure/member.hpp	2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -14,52 +14,28 @@
 #include <boost/preprocessor/cat.hpp>
 #include <boost/preprocessor/dec.hpp>
 #include <boost/preprocessor/comma_if.hpp>
-#include <boost/preprocessor/if.hpp>
-#include <boost/preprocessor/comparison/not_equal.hpp>
 #include <boost/preprocessor/repetition/enum.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
 #include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>
-#include <boost/preprocessor/seq/for_each.hpp>
-#include <boost/preprocessor/seq/pop_back.hpp>
 #include <boost/preprocessor/seq/size.hpp>
 #include <boost/preprocessor/seq/elem.hpp>
-#include <boost/preprocessor/tuple/eat.hpp>
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F(z, data, x) \
-    namespace x {
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I(seq)\
-    BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_OPEN_NAMESPACE_F, ~, BOOST_PP_SEQ_POP_BACK(seq))
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_OPEN_NAMESPACE(seq)\
-    BOOST_PP_IF(BOOST_PP_NOT_EQUAL(BOOST_PP_SEQ_SIZE(seq), 1), BOOST_TYPE_ERASURE_OPEN_NAMEPACE_I, BOOST_PP_TUPLE_EAT(1))(seq)
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_CLOSE_NAMESPACE(seq) \
-    BOOST_PP_REPEAT(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(seq)), } BOOST_PP_TUPLE_EAT(3), ~)
+#include <boost/type_erasure/detail/macro.hpp>
+#include <boost/type_erasure/rebind_any.hpp>
+#include <boost/type_erasure/placeholder.hpp>
+#include <boost/type_erasure/call.hpp>
+#include <boost/type_erasure/concept_interface.hpp>
 
 /** INTERNAL ONLY */
 #define BOOST_TYPE_ERASURE_MEMBER_ARG(z, n, data)  \
     typename ::boost::type_erasure::rebind_any<Base, BOOST_PP_CAT(A, n)>::type BOOST_PP_CAT(a, n)
 
 /** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_NAME_F(z, data, x)\
-    ::x
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq) \
-    BOOST_PP_SEQ_FOR_EACH(BOOST_TYPE_ERASURE_QUALIFIED_NAME_F, ~, seq)
-
-/** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_ID(seq, N) \
+#define BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(seq, N) \
     BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, A)), T>
 
 /** INTERNAL ONLY */
-#define BOOST_TYPE_ERASURE_QUALIFIED_ID_C(seq, N) \
+#define BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(seq, N) \
     BOOST_TYPE_ERASURE_QUALIFIED_NAME(seq)<R(BOOST_PP_ENUM_PARAMS(N, A)), const T>
 
 /** INTERNAL ONLY */
@@ -84,7 +60,7 @@
         class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A),                                      \
         class T, class Base, class Enable>                                                      \
     struct concept_interface<                                                                   \
-        BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N),                                          \
+        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N),                                   \
         Base, T,  Enable> : Base                                                                \
     {                                                                                           \
         typedef void BOOST_PP_CAT(_boost_type_erasure_has_member, member);                      \
@@ -92,7 +68,7 @@
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~))                                 \
         {                                                                                       \
             return ::boost::type_erasure::call(                                                 \
-                BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N)(),                                \
+                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N)(),                         \
                 *this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));                                     \
         }                                                                                       \
     };                                                                                          \
@@ -100,7 +76,7 @@
         class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A),                                      \
         class T, class Base, class Enable>                                                      \
     struct concept_interface<                                                                   \
-        BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N),                                        \
+        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N),                                 \
         Base, T, Enable> : Base                                                                 \
     {                                                                                           \
         typedef void BOOST_PP_CAT(_boost_type_erasure_has_member, member);                      \
@@ -108,13 +84,13 @@
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) const                           \
         {                                                                                       \
             return ::boost::type_erasure::call(                                                 \
-                BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N)(),                              \
+                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N)(),                       \
                 *this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));                                     \
         }                                                                                       \
     };                                                                                          \
     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), class T, class Base>            \
     struct concept_interface<                                                                   \
-        BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N),                                          \
+        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N),                                   \
         Base, T, typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base    \
     {                                                                                           \
         using Base::member;                                                                     \
@@ -122,13 +98,13 @@
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~))                                 \
         {                                                                                       \
             return ::boost::type_erasure::call(                                                 \
-                BOOST_TYPE_ERASURE_QUALIFIED_ID(qual_name, N)(),                                \
+                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID(qual_name, N)(),                         \
                 *this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));                                     \
         }                                                                                       \
     };                                                                                          \
     template<class R BOOST_PP_ENUM_TRAILING_PARAMS(N, class A), class T, class Base>            \
     struct concept_interface<                                                                   \
-        BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N),                                        \
+        BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N),                                 \
         Base, T,                                                                                \
         typename Base::BOOST_PP_CAT(_boost_type_erasure_has_member, member)> : Base             \
     {                                                                                           \
@@ -137,7 +113,7 @@
             BOOST_PP_ENUM(N, BOOST_TYPE_ERASURE_MEMBER_ARG, ~)) const                           \
         {                                                                                       \
             return ::boost::type_erasure::call(                                                 \
-                BOOST_TYPE_ERASURE_QUALIFIED_ID_C(qual_name, N)(),                              \
+                BOOST_TYPE_ERASURE_MEMBER_QUALIFIED_ID_C(qual_name, N)(),                       \
                 *this BOOST_PP_ENUM_TRAILING_PARAMS(N, a));                                     \
         }                                                                                       \
     };                                                                                          \
Modified: sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam
==============================================================================
--- sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam	(original)
+++ sandbox/type_erasure/libs/type_erasure/test/Jamfile.jam	2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -35,6 +35,7 @@
 run test_same_type.cpp /boost//unit_test_framework ;
 run test_member.cpp /boost//unit_test_framework ;
 run test_null.cpp /boost//unit_test_framework ;
+run test_free.cpp /boost//unit_test_framework ;
 
 compile-fail fail_default_construct.cpp ;
 compile-fail fail_construct_mismatch.cpp ;
Added: sandbox/type_erasure/libs/type_erasure/test/test_free.cpp
==============================================================================
--- (empty file)
+++ sandbox/type_erasure/libs/type_erasure/test/test_free.cpp	2012-09-19 18:46:36 EDT (Wed, 19 Sep 2012)
@@ -0,0 +1,99 @@
+// Boost.TypeErasure library
+//
+// Copyright 2012 Steven Watanabe
+//
+// Distributed under the Boost Software License Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// $Id$
+
+#include <boost/type_erasure/any.hpp>
+#include <boost/type_erasure/builtin.hpp>
+#include <boost/type_erasure/free.hpp>
+#include <boost/mpl/vector.hpp>
+
+#define BOOST_TEST_MAIN
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::type_erasure;
+
+struct model {
+    explicit model(int v) : val(v) {}
+    int val;
+};
+
+int f1(model& m) { return m.val; }
+int f1(model& m, int i) { return m.val + i; }
+
+BOOST_TYPE_ERASURE_FREE((global_has_f1_1), f1, 1);
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_1) {
+    typedef ::boost::mpl::vector<
+        global_has_f1_1<int(_self&)>,
+        copy_constructible<> > concept_type;
+    model m(10);
+    any<concept_type> x(m);
+    BOOST_CHECK_EQUAL(f1(x), 10);
+}
+
+BOOST_TYPE_ERASURE_FREE((ns1)(ns2)(ns_has_f1_1), f1, 1);
+
+BOOST_AUTO_TEST_CASE(test_ns_has_f1_1) {
+    typedef ::boost::mpl::vector<
+        ns1::ns2::ns_has_f1_1<int(_self&)>,
+        copy_constructible<> > concept_type;
+    model m(10);
+    any<concept_type> x(m);
+    BOOST_CHECK_EQUAL(f1(x), 10);
+}
+
+struct model_const {
+    explicit model_const(int v) : val(v) {}
+    int val;
+};
+
+int f1(const model_const& m) { return m.val; }
+int f1(const model_const& m, int i) { return m.val + i; }
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_1_const) {
+    typedef ::boost::mpl::vector<
+        ns1::ns2::ns_has_f1_1<int(const _self&)>,
+        copy_constructible<> > concept_type;
+    model_const m(10);
+    any<concept_type> x(m);
+    BOOST_CHECK_EQUAL(f1(x), 10);
+}
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_1_void) {
+    typedef ::boost::mpl::vector<
+        global_has_f1_1<void(_self&)>,
+        copy_constructible<> > concept_type;
+    model m(10);
+    any<concept_type> x(m);
+    f1(x);
+}
+
+BOOST_TYPE_ERASURE_FREE((global_has_f1_2), f1, 2);
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_overload) {
+    typedef ::boost::mpl::vector<
+        global_has_f1_1<int(_self&)>,
+        global_has_f1_2<int(_self&, int)>,
+        copy_constructible<> > concept_type;
+    model m(10);
+    any<concept_type> x(m);
+    BOOST_CHECK_EQUAL(f1(x), 10);
+    BOOST_CHECK_EQUAL(f1(x, 5), 15);
+}
+
+BOOST_AUTO_TEST_CASE(test_global_has_f1_overload_const) {
+    typedef ::boost::mpl::vector<
+        global_has_f1_1<int(const _self&)>,
+        global_has_f1_2<int(const _self&, int)>,
+        copy_constructible<> > concept_type;
+    model_const m(10);
+    any<concept_type> x(m);
+    BOOST_CHECK_EQUAL(f1(x), 10);
+    BOOST_CHECK_EQUAL(f1(x, 5), 15);
+}