#ifndef MACE_FWD_HPP_ #define MACE_FWD_HPP_ #include #include namespace detail { template struct add { typedef decltype( *((A*)0) + *((typename std::remove_reference::type*)0) ) type; }; template struct add_eq { typedef decltype( *((A*)0) += *((typename std::remove_reference::type*)0) ) type; }; template struct sub { typedef decltype( *((A*)0) - *((typename std::remove_reference::type*)0) ) type; }; template struct sub_eq { typedef decltype( *((A*)0) -= *((typename std::remove_reference::type*)0) ) type; }; template struct insert_op { typedef decltype( *((A*)0) << *((typename std::remove_reference::type*)0) ) type; }; template struct extract_op { A* a; U* u; typedef decltype( *a >> *u ) type; }; } template class fwd { public: template fwd( U&& u ) { static_assert( sizeof(_store) >= sizeof(*this), "Failed to reserve enough space" ); new (this) T( std::forward(u) ); } fwd() { static_assert( sizeof(_store) >= sizeof(*this), "Failed to reserve enough space" ); new (this) T(); } fwd( const fwd& f ){ new (this) T( *f ); } fwd( fwd&& f ){ new (this) T( std::move(*f) ); } template operator U () { return *((T*)this); } template operator const U&() { return *((const T*)this); } T& operator*() { return *((T*)this); } const T& operator*()const { return *((const T*)this); } const T* operator->()const { return ((const T*)this); } T* operator->(){ return ((T*)this); } bool operator !()const { return !(**this); } template friend auto operator + ( const fwd& x, U&& u ) -> typename detail::add::type { return *x+std::forward(u); } template auto operator += ( U&& u ) -> typename detail::add_eq::type { return **this+=std::forward(u); } template friend auto operator - ( const fwd& x, U&& u ) -> typename detail::sub::type { return *x-std::forward(u); } template auto operator -= ( U&& u ) -> typename detail::sub_eq::type { return **this-=std::forward(u); } template friend auto operator << ( U& u, const fwd& f ) -> typename detail::insert_op::type { return u << *f; } template friend auto operator >> ( U& u, fwd& f ) -> typename detail::extract_op::type { return u >> *f; } ~fwd() { ((T*)this)->~T(); } private: union { double _force_align; char _data[S]; } _store; }; #endif struct test; class A { public: A(); private: fwd x; }; struct test { test( int _a ):a(_a),b(99){} operator double()const { return a/b; } bool operator!()const { return true; } friend test operator + ( const test& t, double x ) { return test(t.a + x); } test& operator += ( double x ) { a += x; return *this; } char a; int b; }; #include std::ostream& operator<<(std::ostream& o, const test& t ) { return o << t.a << t.b; } std::istream& operator>>(std::istream& o, test& t ) { return o >> t.a >> t.b; } A::A():x(500){ std::cerr<a<> x; std::cerr<