]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/libs/parameter/test/preprocessor_deduced.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / parameter / test / preprocessor_deduced.cpp
index ae310dc6c9d739bdb5e45c227fa8b29a994f205d..f3c89172dc3f2c3a6188ad6be5535c777739af16 100644 (file)
-// Copyright Daniel Wallin 2006. Use, modification and distribution is
-// subject to the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+// Copyright Daniel Wallin 2006.
+// 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)
 
+#include <boost/parameter/config.hpp>
 #include <boost/parameter/preprocessor.hpp>
 #include <boost/parameter/name.hpp>
-#include <boost/type_traits/is_convertible.hpp>
 #include <boost/tuple/tuple.hpp>
+#include <map>
 #include <string>
 #include "basics.hpp"
 
-#ifndef BOOST_NO_SFINAE
-# include <boost/utility/enable_if.hpp>
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+#include <boost/parameter/value_type.hpp>
+#include <boost/mp11/map.hpp>
+#include <boost/core/enable_if.hpp>
+#include <type_traits>
+#else
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#if !defined(BOOST_NO_SFINAE)
+#include <boost/parameter/value_type.hpp>
+#include <boost/mpl/has_key.hpp>
+#include <boost/core/enable_if.hpp>
+#include <boost/type_traits/is_same.hpp>
+#endif
 #endif
 
 namespace test {
 
-namespace mpl = boost::mpl;
+    BOOST_PARAMETER_NAME(expected)
+    BOOST_PARAMETER_NAME(x)
+    BOOST_PARAMETER_NAME(y)
+    BOOST_PARAMETER_NAME(z)
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+    template <typename To>
+    struct predicate
+    {
+        template <typename From, typename Args>
+        using fn = std::is_convertible<From,To>;
+    };
+
+    BOOST_PARAMETER_FUNCTION((int), f, test::tag,
+        (required
+            (expected, *)
+        )
+        (deduced
+            (required
+                (x, *(test::predicate<int>))
+                (y, *(test::predicate<std::string>))
+            )
+        )
+    )
+#else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
+    struct predicate_int
+    {
+        template <typename From, typename Args>
+        struct apply
+          : boost::mpl::if_<
+                boost::is_convertible<From,int>
+              , boost::mpl::true_
+              , boost::mpl::false_
+            >
+        {
+        };
+    };
+
+    struct predicate_string
+    {
+        template <typename From, typename Args>
+        struct apply
+          : boost::mpl::if_<
+                boost::is_convertible<From,std::string>
+              , boost::mpl::true_
+              , boost::mpl::false_
+            >
+        {
+        };
+    };
+
+    BOOST_PARAMETER_FUNCTION((int), f, test::tag,
+        (required
+            (expected, *)
+        )
+        (deduced
+            (required
+                (x, *(test::predicate_int))
+                (y, *(test::predicate_string))
+            )
+        )
+    )
+#endif  // BOOST_PARAMETER_CAN_USE_MP11
+    {
+        BOOST_TEST(test::equal(x, boost::tuples::get<0>(expected)));
+        BOOST_TEST(test::equal(y, boost::tuples::get<1>(expected)));
+        return 1;
+    }
 
-using mpl::_;
-using boost::is_convertible;
+    struct X 
+    {
+        X(int x_ = -1) : x(x_)
+        {
+        }
 
-BOOST_PARAMETER_NAME(expected)
-BOOST_PARAMETER_NAME(x)
-BOOST_PARAMETER_NAME(y)
-BOOST_PARAMETER_NAME(z)
+        bool operator==(X const& other) const
+        {
+            return this->x == other.x;
+        }
 
-// Sun has problems with this syntax:
-//
-//   template1< r* ( template2<x> ) >
-//
-// Workaround: factor template2<x> into a separate typedef
-typedef is_convertible<_, int> predicate1;
-typedef is_convertible<_, std::string> predicate2;
+        int x;
+    };
 
-#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x580))
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+    BOOST_PARAMETER_FUNCTION((int), g, test::tag,
+        (required
+            (expected, *)
+        )
+        (deduced
+            (required
+                (x, *(test::predicate<int>))
+                (y, *(test::predicate<std::string>))
+            )
+            (optional
+                (z, *(test::predicate<test::X>), test::X())
+            )
+        )
+    )
+#else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
+    struct predicate_X
+    {
+        template <typename From, typename Args>
+        struct apply
+          : boost::mpl::if_<
+                boost::is_convertible<From,test::X>
+              , boost::mpl::true_
+              , boost::mpl::false_
+            >
+        {
+        };
+    };
 
-BOOST_PARAMETER_FUNCTION((int), f, tag,
-    (required
-       (expected, *)
+    BOOST_PARAMETER_FUNCTION((int), g, tag,
+        (required
+            (expected, *)
+        )
+        (deduced
+            (required
+                (x, *(test::predicate_int))
+                (y, *(test::predicate_string))
+            )
+            (optional
+                (z, *(test::predicate_X), test::X())
+            )
+        )
     )
-    (deduced
-       (required
-          (x, *(predicate1))
-          (y, *(predicate2))
-       )
+#endif  // BOOST_PARAMETER_CAN_USE_MP11
+    {
+        BOOST_TEST(test::equal(x, boost::tuples::get<0>(expected)));
+        BOOST_TEST(test::equal(y, boost::tuples::get<1>(expected)));
+        BOOST_TEST(test::equal(z, boost::tuples::get<2>(expected)));
+        return 1;
+    }
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+    BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag,
+        (deduced
+            (required
+                (x, *(test::predicate<std::string>))
+            )
+        )
     )
-)
 #else
-BOOST_PARAMETER_FUNCTION((int), f, tag,
-    (required
-       (expected, *)
+    BOOST_PARAMETER_FUNCTION((int), sfinae, test::tag,
+        (deduced
+            (required
+                (x, *(test::predicate_string))
+            )
+        )
     )
-    (deduced
-       (required
-          (x, *(is_convertible<_, int>))
-          (y, *(is_convertible<_, std::string>))
-       )
-    )
-)
-#endif 
-{
-    assert(equal(x, boost::tuples::get<0>(expected)));
-    assert(equal(y, boost::tuples::get<1>(expected)));
-    return 1;
-}
+#endif
+    {
+        return 1;
+    }
 
-struct X 
-{
-    X(int x = -1)
-      : x(x)
-    {}
-    
-    bool operator==(X const& other) const
+#if !defined(BOOST_NO_SFINAE)
+    // On compilers that actually support SFINAE, add another overload
+    // that is an equally good match and can only be in the overload set
+    // when the others are not.  This tests that the SFINAE is actually
+    // working.  On all other compilers we're just checking that everything
+    // about SFINAE-enabled code will work, except of course the SFINAE.
+    template <typename A0>
+    typename boost::enable_if<
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+        std::is_same<int,A0>
+#else
+        typename boost::mpl::if_<
+            boost::is_same<int,A0>
+          , boost::mpl::true_
+          , boost::mpl::false_
+        >::type
+#endif
+      , int
+    >::type
+        sfinae(A0 const& a0)
     {
-        return x == other.x;
+        return 0;
     }
-    
-    int x;
-};
 
-typedef is_convertible<_, X> predicate3;  // SunPro workaround; see above
+#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) || \
+    !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+    // Test support for two different Boost.Parameter-enabled
+    // function call operator overloads.
+    class char_read_base
+    {
+        int index;
+        char const* key;
+
+     public:
+        template <typename Args>
+        explicit char_read_base(Args const& args)
+          : index(args[test::_y]), key(args[test::_z])
+        {
+        }
+
+        BOOST_PARAMETER_FUNCTION_CALL_OPERATOR((void), test::tag,
+            (deduced
+                (required
+                    (y, (int))
+                    (z, (char const*))
+                )
+            )
+        )
+        {
+            this->index = y;
+            this->key = z;
+        }
+
+        BOOST_PARAMETER_CONST_FUNCTION_CALL_OPERATOR((char), test::tag,
+            (deduced
+                (required
+                    (y, (bool))
+                    (z, (std::map<char const*,std::string>))
+                )
+            )
+        )
+        {
+            return y ? (
+                (z.find(this->key)->second)[this->index]
+            ) : this->key[this->index];
+        }
+    };
+
+    struct char_reader : public char_read_base
+    {
+        BOOST_PARAMETER_CONSTRUCTOR(char_reader, (char_read_base), test::tag,
+            (deduced
+                (required
+                    (y, (int))
+                    (z, (char const*))
+                )
+            )
+        )
+    };
+#endif  // MSVC-11.0-
 
-BOOST_PARAMETER_FUNCTION((int), g, tag,
-    (required
-      (expected, *)
+    // Test Boost.Parameter-enabled functions
+    // with parameter-dependent return types.
+#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE)
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+    BOOST_PARAMETER_FUNCTION(
+        (
+            boost::lazy_enable_if<
+                boost::mp11::mp_map_contains<Args,test::tag::y>
+              , boost::parameter::value_type<Args,test::tag::y>
+            >
+        ), return_y, test::tag,
+        (deduced
+            (required
+                (x, (std::map<char const*,std::string>))
+                (y, (char const*))
+            )
+            (optional
+                (z, (int), 4)
+            )
+        )
     )
-    (deduced
-       (required
-          (x, *(is_convertible<_, int>))
-          (y, *(is_convertible<_, std::string>))
-       )
-       (optional
-          (z, *(predicate3), X())
-       )
+#else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
+    BOOST_PARAMETER_FUNCTION(
+        (
+            boost::lazy_enable_if<
+                typename boost::mpl::has_key<Args,test::tag::y>::type
+              , boost::parameter::value_type<Args,test::tag::y>
+            >
+        ), return_y, test::tag,
+        (deduced
+            (required
+                (x, (std::map<char const*,std::string>))
+                (y, (char const*))
+            )
+            (optional
+                (z, (int), 4)
+            )
+        )
     )
-)
-{
-    assert(equal(x, boost::tuples::get<0>(expected)));
-    assert(equal(y, boost::tuples::get<1>(expected)));
-    assert(equal(z, boost::tuples::get<2>(expected)));
-    return 1;
-}
+#endif  // BOOST_PARAMETER_CAN_USE_MP11
+    {
+        return y;
+    }
+#endif  // LIBS_PARAMETER_TEST_COMPILE_FAILURE
+#endif  // BOOST_NO_SFINAE
 
-BOOST_PARAMETER_FUNCTION(
-    (int), sfinae, tag,
-    (deduced
-      (required
-        (x, *(predicate2))
-      )
+#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE)
+    BOOST_PARAMETER_FUNCTION(
+        (typename boost::parameter::value_type<Args,test::tag::y>::type),
+        return_y, test::tag,
+        (deduced
+            (required
+                (x, (std::map<char const*,std::string>))
+                (y, (char const*))
+            )
+            (optional
+                (z, (int), 4)
+            )
+        )
     )
-)
-{
-    return 1;
-}
-
-#ifndef BOOST_NO_SFINAE
-// On compilers that actually support SFINAE, add another overload
-// that is an equally good match and can only be in the overload set
-// when the others are not.  This tests that the SFINAE is actually
-// working.  On all other compilers we're just checking that
-// everything about SFINAE-enabled code will work, except of course
-// the SFINAE.
-template<class A0>
-typename boost::enable_if<boost::is_same<int,A0>, int>::type
-sfinae(A0 const& a0)
-{
-    return 0;
-}
-#endif
-
+    {
+        return y;
+    }
+#endif  // defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE)
 } // namespace test
 
-using boost::make_tuple;
-
-// make_tuple doesn't work with char arrays.
-char const* str(char const* s)
-{
-    return s;
-}
+#include <boost/core/lightweight_test.hpp>
 
 int main()
 {
-    using namespace test;
-
-    f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
-    f(make_tuple(0, str("foo")), _x = 0, _y = "foo");
-    f(make_tuple(0, str("foo")), 0, "foo");
-    f(make_tuple(0, str("foo")), "foo", 0);
-    f(make_tuple(0, str("foo")), _y = "foo", 0);
-    f(make_tuple(0, str("foo")), _x = 0, "foo");
-    f(make_tuple(0, str("foo")), 0, _y = "foo");
-
-    g(make_tuple(0, str("foo"), X()), _x = 0, _y = "foo");
-    g(make_tuple(0, str("foo"), X()), 0, "foo");
-    g(make_tuple(0, str("foo"), X()), "foo", 0);
-    g(make_tuple(0, str("foo"), X()), _y = "foo", 0);   
-    g(make_tuple(0, str("foo"), X()), _x = 0, "foo");
-    g(make_tuple(0, str("foo"), X()), 0, _y = "foo");
-
-    g(make_tuple(0, str("foo"), X(1)), 0, _y = "foo", X(1));
-    g(make_tuple(0, str("foo"), X(1)), X(1), 0, _y = "foo");
-
-#ifndef BOOST_NO_SFINAE
-    assert(sfinae("foo") == 1);
-    assert(sfinae(0) == 0);
+    test::f(
+        boost::make_tuple(0, std::string("foo"))
+      , test::_x = 0
+      , test::_y = std::string("foo")
+    );
+    test::f(
+        boost::make_tuple(0, std::string("foo"))
+      , 0
+      , std::string("foo")
+    );
+    test::f(
+        boost::make_tuple(0, std::string("foo"))
+      , std::string("foo")
+      , 0
+    );
+    test::f(
+        boost::make_tuple(0, std::string("foo"))
+      , test::_y = std::string("foo")
+      , 0
+    );
+    test::f(
+        boost::make_tuple(0, std::string("foo"))
+      , test::_x = 0
+      , std::string("foo")
+    );
+    test::f(
+        boost::make_tuple(0, std::string("foo"))
+      , 0
+      , test::_y = std::string("foo")
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X())
+      , test::_x = 0
+      , test::_y = std::string("foo")
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X())
+      , 0
+      , std::string("foo")
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X())
+      , std::string("foo")
+      , 0
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X())
+      , test::_y = std::string("foo")
+      , 0
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X())
+      , test::_x = 0
+      , std::string("foo")
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X())
+      , 0
+      , test::_y = std::string("foo")
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X(1))
+      , 0
+      , test::_y = std::string("foo")
+      , test::X(1)
+    );
+    test::g(
+        boost::make_tuple(0, std::string("foo"), test::X(1))
+      , test::X(1)
+      , 0
+      , test::_y = std::string("foo")
+    );
+
+    std::map<char const*,std::string> k2s;
+#if !defined(BOOST_NO_SFINAE)
+    char const* keys[] = {"foo", "bar", "baz"};
+    BOOST_TEST_EQ(1, test::sfinae(keys[0]));
+    BOOST_TEST_EQ(0, test::sfinae(0));
+#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE_VENDOR_SPECIFIC) || \
+    !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+    k2s[keys[0]] = std::string("qux");
+    k2s[keys[1]] = std::string("wmb");
+    k2s[keys[2]] = std::string("zxc");
+    test::char_reader r(keys[0], 0);
+    BOOST_TEST_EQ('q', (r(k2s, true)));
+    BOOST_TEST_EQ('f', (r(k2s, false)));
+    r(keys[1], 1);
+    BOOST_TEST_EQ('m', (r(k2s, true)));
+    BOOST_TEST_EQ('a', (r(k2s, false)));
+    r(keys[2], 2);
+    BOOST_TEST_EQ('c', (r(k2s, true)));
+    BOOST_TEST_EQ('z', (r(k2s, false)));
+#endif  // MSVC-11.0-
+#if !defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE)
+    BOOST_TEST_EQ(keys[1], test::return_y(2, k2s, keys[1]));
+#endif
+#endif  // BOOST_NO_SFINAE
+
+#if defined(LIBS_PARAMETER_TEST_COMPILE_FAILURE)
+    BOOST_TEST_EQ(keys[1], test::return_y(2, k2s, keys[1]));
 #endif
 
-    return 0;
+    return boost::report_errors();
 }