diff --git a/test/deduced.cpp b/test/deduced.cpp new file mode 100755 index 0000000..2d744a2 --- /dev/null +++ b/test/deduced.cpp @@ -0,0 +1,180 @@ +// 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) + +#include +#include +#include +#include +#include "basics.hpp" + +namespace parameter = boost::parameter; +namespace mpl = boost::mpl; + +struct not_present_tag {}; +not_present_tag not_present; + +BOOST_PARAMETER_NAME(x) +BOOST_PARAMETER_NAME(y) +BOOST_PARAMETER_NAME(z) + +template +struct assert_expected +{ + assert_expected(E const& e, ArgPack const& args) + : expected(e) + , args(args) + {} + + template + bool check_not_present(T const&) const + { + BOOST_MPL_ASSERT((boost::is_same)); + return true; + } + + template + bool check(K const& k, not_present_tag const&, long) const + { + return check_not_present(args[k | not_present]); + } + + template + bool check(K const& k, Expected const& expected, int) const + { + return test::equal(args[k], expected); + } + + template + void operator()(K) const + { + parameter::keyword const& k = parameter::keyword::get(); + assert(check(k, expected[k], 0L)); + } + + E const& expected; + ArgPack const& args; +}; + +template +void check0(E const& e, ArgPack const& args) +{ + mpl::for_each(assert_expected(e, args)); +} + +template +void check(E const& e, A0 const& a0) +{ + check0(e, P()(a0)); +} + +template +void check(E const& e, A0 const& a0, A1 const& a1) +{ + check0(e, P()(a0,a1)); +} + +template +void check(E const& e, A0 const& a0, A1 const& a1, A2 const& a2) +{ + check0(e, P()(a0,a1,a2)); +} + +int main() +{ + using namespace parameter; + + check< + parameters< + tag::x + , tag::y + > + >( + (_x = 0, _y = 1) + , 0 + , 1 + ); + + check< + parameters< + tag::x + , required, boost::is_convertible > + , optional, boost::is_convertible > + > + >( + (_x = 0, _y = not_present, _z = "foo") + , _x = 0 + , "foo" + ); + + check< + parameters< + tag::x + , required, boost::is_convertible > + , optional, boost::is_convertible > + > + >( + (_x = 0, _y = 1, _z = "foo") + , 0 + , "foo" + , 1 + ); + + check< + parameters< + tag::x + , required, boost::is_convertible > + , optional, boost::is_convertible > + > + >( + (_x = 0, _y = 1, _z = "foo") + , 0 + , 1 + , "foo" + ); + + check< + parameters< + tag::x + , required, boost::is_convertible > + , optional, boost::is_convertible > + > + >( + (_x = 0, _y = 1, _z = "foo") + , 0 + , _y = 1 + , "foo" + ); + + check< + parameters< + tag::x + , required, boost::is_convertible > + , optional, boost::is_convertible > + > + >( + (_x = 0, _y = 1, _z = "foo") + , _z = "foo" + , _x = 0 + , 1 + ); + + // Fails becasue of parameters.hpp:428 +/* + check< + parameters< + tag::x + , required, boost::is_convertible > + , optional, boost::is_convertible > + > + >( + (_x = 0, _y = 1, _z = "foo") + , _x = 0 + , (long*)0 + , 1 + ); +*/ + + return 0; +}; + diff --git a/test/preprocessor_deduced.cpp b/test/preprocessor_deduced.cpp new file mode 100755 index 0000000..04ca1fb --- /dev/null +++ b/test/preprocessor_deduced.cpp @@ -0,0 +1,110 @@ +// 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) + +#include +#include +#include +#include +#include +#include "basics.hpp" + +namespace test { + +namespace mpl = boost::mpl; + +using mpl::_; +using boost::is_convertible; + +BOOST_PARAMETER_NAME(expected) +BOOST_PARAMETER_NAME(x) +BOOST_PARAMETER_NAME(y) +BOOST_PARAMETER_NAME(z) + +BOOST_PARAMETER_FUNCTION((int), f, tag, + (required + (expected, *) + ) + (deduced + (required + (x, *(is_convertible<_, int>)) + (y, *(is_convertible<_, std::string>)) + ) + ) +) +{ + assert(equal(x, boost::tuples::get<0>(expected))); + assert(equal(y, boost::tuples::get<1>(expected))); + return 1; +} + +struct X +{ + X(int x = -1) + : x(x) + {} + + bool operator==(X const& other) const + { + return x == other.x; + } + + int x; +}; + +BOOST_PARAMETER_FUNCTION((int), g, tag, + (required + (expected, *) + ) + (deduced + (required + (x, *(is_convertible<_, int>)) + (y, *(is_convertible<_, std::string>)) + ) + (optional + (z, *(is_convertible<_, X>), X()) + ) + ) +) +{ + 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; +} + +} // namespace test + +using boost::make_tuple; + +// make_tuple doesn't work with char arrays. +char const* str(char const* s) +{ + return s; +} + +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"); + + return 0; +} + diff --git a/test/python_test.cpp b/test/python_test.cpp new file mode 100755 index 0000000..a9612ae --- /dev/null +++ b/test/python_test.cpp @@ -0,0 +1,159 @@ +// 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) + +#include +#include +#include +#include +#include + +namespace test { + +BOOST_PARAMETER_KEYWORD(tag, x) +BOOST_PARAMETER_KEYWORD(tag, y) +BOOST_PARAMETER_KEYWORD(tag, z) + +struct Xbase +{ + // We need the disable_if part for VC7.1/8.0. + template + Xbase( + Args const& args + , typename boost::disable_if< + boost::is_base_and_derived + >::type* = 0 + ) + : value(std::string(args[x | "foo"]) + args[y | "bar"]) + {} + + std::string value; +}; + +struct X : Xbase +{ + BOOST_PARAMETER_CONSTRUCTOR(X, (Xbase), tag, + (optional + (x, *) + (y, *) + ) + ) + + BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((int), f, tag, + (required + (x, *) + (y, *) + ) + (optional + (z, *) + ) + ) + { + return args[x] + args[y] + args[z | 0]; + } + + BOOST_PARAMETER_BASIC_MEMBER_FUNCTION((std::string), g, tag, + (optional + (x, *) + (y, *) + ) + ) + { + return std::string(args[x | "foo"]) + args[y | "bar"]; + } + + BOOST_PARAMETER_MEMBER_FUNCTION((X&), h, tag, + (optional (x, *, "") (y, *, "")) + ) + { + return *this; + } + + template + X& operator()(A0 const& a0) + { + return *this; + } +}; + +} // namespace test + +struct f_fwd +{ + template + R operator()(boost::type, T& self, A0 const& a0, A1 const& a1, A2 const& a2) + { + return self.f(a0,a1,a2); + } +}; + +struct g_fwd +{ + template + R operator()(boost::type, T& self, A0 const& a0, A1 const& a1) + { + return self.g(a0,a1); + } +}; + +struct h_fwd +{ + template + R operator()(boost::type, T& self, A0 const& a0, A1 const& a1) + { + return self.h(a0,a1); + } +}; + +BOOST_PYTHON_MODULE(python_test_ext) +{ + namespace mpl = boost::mpl; + using namespace test; + using namespace boost::python; + + class_("X") + .def( + boost::parameter::python::init< + mpl::vector< + tag::x*(std::string), tag::y*(std::string) + > + >() + ) + .def( + "f" + , boost::parameter::python::function< + f_fwd + , mpl::vector< + int, tag::x(int), tag::y(int), tag::z*(int) + > + >() + ) + .def( + "g" + , boost::parameter::python::function< + g_fwd + , mpl::vector< + std::string, tag::x*(std::string), tag::y*(std::string) + > + >() + ) + .def( + "h" + , boost::parameter::python::function< + h_fwd + , mpl::vector< + X&, tag::x*(std::string), tag::y*(std::string) + > + >() + , return_arg<>() + ) + .def( + boost::parameter::python::call< + mpl::vector< + X&, tag::x(int) + > + >() [ return_arg<>() ] + ) + .def_readonly("value", &X::value); +} + diff --git a/test/python_test.py b/test/python_test.py new file mode 100644 index 0000000..ce3b81c --- /dev/null +++ b/test/python_test.py @@ -0,0 +1,41 @@ +# 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) + +''' +>>> from python_test_ext import X +>>> x = X(y = 'baz') +>>> x.value +'foobaz' +>>> x.f(1,2) +3 +>>> x.f(1,2,3) +6 +>>> x.f(1,2, z = 3) +6 +>>> x.f(z = 3, y = 2, x = 1) +6 +>>> x.g() +'foobar' +>>> x.g(y = "baz") +'foobaz' +>>> x.g(x = "baz") +'bazbar' +>>> x.g(y = "foo", x = "bar") +'barfoo' +>>> y = x.h(x = "bar", y = "foo") +>>> assert x == y +>>> y = x(0) +>>> assert x == y +''' + +def run(args = None): + if args is not None: + import sys + sys.argv = args + import doctest, python_test + return doctest.testmod(python_test) + +if __name__ == '__main__': + import sys + sys.exit(run()[0])