#include <iostream>

#include <boost/type_traits/is_convertible.hpp>
#include <boost/utility/enable_if.hpp>

// rv<T>& emulates T&&
template< class T >
class rv : public T
{
    rv();
    rv(rv const &);
    rv& operator=(rv const &);
};

template< class T >
struct has_move_emulation
    : boost::is_convertible< T, rv<T>& >
{ };

// *** NEW EMULATED RVALUE REFERENCE ***
// generic_rv< F, Result > also emulates an rvalue reference, but in a kind of
// type-erased way.  The actual object referred to is referenced by a void
// pointer.  To be able to cast the void pointer back to a pointer-to-object, we
// need to package the void pointer together with some kind of dispatching
// mechanism.  We use a function reference to an instantiation of
// cast_forward<T>.
template< class F, class Result = void >
struct generic_rv
{
    typedef Result (&cast_forward_type)(F, void*);

    generic_rv(cast_forward_type cast_forward, void* p)
        : m_cast_forward(cast_forward),
          m_p(p)
    { }

    Result cast_forward(F f) const
    { return m_cast_forward(f, m_p); }

    template< class T >
    static Result cast_forward(F f, void* const p)
    { return f(static_cast< rv<T>& >(*static_cast< T* >(p))); }

private:
    cast_forward_type m_cast_forward;
    void* m_p;
};

// X is just a typical move-emulation-enabled class.
struct X
{
    X() { }
    X(X const &) { }
    X(rv<X>&) { }

    X& operator=(X) { return *this; }
    X& operator=(rv<X>&) { return *this; }

    operator rv<X>&() { return *static_cast< rv<X>* >(this); }
    operator rv<X> const &() const { return *static_cast< rv<X> const * >(this); }

    // *** NEW CONVERSION OPERATOR ***
    // X provides an implicit conversion to generic_rv.
    template< class F, class Result >
    operator generic_rv< F, Result >()
    {
        return generic_rv< F, Result >(
            generic_rv< F, Result >::template cast_forward<X>,
            static_cast< void* >(this)
        );
    }
};

struct some_fn
{
    template< class T >
    void operator()(T&) const
    { std::cout << "some_fn::operator()(T&) const" << std::endl; }

    template< class T >
    typename boost::disable_if< has_move_emulation<T> >::type
    operator()(T const &) const
    { std::cout << "some_fn::operator()(T const &) const" << std::endl; }

    // Notice that this overload requires template parameter deduction, hence
    // the compiler cannot apply an implicit conversion to rv<T>& from rvalues
    // of move-emulation-enabled types.  In other words, this overload can only
    // bind to *explicitly* created emulated rvalue references, not to "real"
    // rvalues :(
    template< class T >
    void operator()(rv<T>&) const
    { std::cout << "some_fn::operator()(rv<T>&) const" << std::endl; }

    // *** NEW FUNCTION OVERLOAD TO CAPTURE RVALUES ***
    // Since this overload requires no template parameter deduction, the
    // compiler *can* apply an implicit conversion to generic_rv<...> from
    // rvalues of move-emulation-enabled types.  Yes, there *may* be some
    // runtime overhead from the indirect dispatch, but that will often be
    // preferable to copying x!
    void operator()(generic_rv< some_fn > const x) const
    { return x.cast_forward(*this); }
};

template< class T > T make() { return T(); }

int main(int argc, char* argv[])
{
    int a = 0;
    int const b = 0;
    some_fn()(a);             // some_fn::operator()(T&) const
    some_fn()(b);             // some_fn::operator()(T const &) const
    some_fn()(make< int >()); // some_fn::operator()(T const &) const
    X x;
    X const y;
    some_fn()(x);             // some_fn::operator()(T&) const
    some_fn()(y);             // some_fn::operator()(T&) const
    some_fn()(make<X>());     // some_fn::operator()(rv<T>&) const
    some_fn()(static_cast< rv<X>& >(make<X>())); // some_fn::operator()(rv<T>&) const
    return 0;
}
