
#include <math.h>
#include <boost/python.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/python.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/parameter.hpp>

#define LAZY_EVAL
#define PYTHON_MODULE

namespace test {

    BOOST_PARAMETER_NAME(x)
    BOOST_PARAMETER_NAME(y)

    struct Op {
        Op(const char* string)
            : string_(string)
        {}

        const char* operator() () const {
            return string_;
        }

    private:
        const char* string_;
    };

    struct Xbase
    {
        // We need the disable_if part for VC7.1/8.0.
        template <class Args>
        Xbase(
            Args const& args
            , typename boost::disable_if<
            boost::is_base_and_derived<Xbase, Args>
            >::type* = 0 )
#ifdef LAZY_EVAL
            : value(std::string(args[_x | "foo"]) + args[_y || Op("bar")])
#else
              : value(std::string(args[_x | "foo"]) + args[_y | "bar"])
#endif
        {}

    private:
        std::string value;
    };

    struct X : Xbase
    {
        BOOST_PARAMETER_CONSTRUCTOR(X, (Xbase), tag,
                                    (optional
                                     (x, *)
                                     (y, *)
                                        )
            )
    };

} // namespace test

#ifdef PYTHON_MODULE

BOOST_PYTHON_MODULE(python_test_ext)
{
    namespace mpl = boost::mpl;
    using namespace test;
    using namespace boost::python;

    class_<X>("X")
        .def(
            boost::parameter::python::init<
            mpl::vector<
            tag::x*(std::string), tag::y*(std::string) > >() );
}

#else

int main() {
    using namespace test;

    X x1, x2(_x="foofoo"), x3(_y="barbar"),
        x4(_x="foofoo", _y="barbar");
}

#endif
