#pragma once #include #include #include namespace fc { namespace detail { template struct add { typedef decltype( *((A*)0) + *((typename fc::remove_reference::type*)0) ) type; }; template struct add_eq { typedef decltype( *((A*)0) += *((typename fc::remove_reference::type*)0) ) type; }; template struct sub { typedef decltype( *((A*)0) - *((typename fc::remove_reference::type*)0) ) type; }; template struct sub_eq { typedef decltype( *((A*)0) -= *((typename fc::remove_reference::type*)0) ) type; }; template struct insert_op { typedef decltype( *((A*)0) << *((typename fc::remove_reference::type*)0) ) type; }; template struct extract_op { A* a; U* u; typedef decltype( *a >> *u ) type; }; } template auto operator + ( const fwd& x, U&& u ) -> typename detail::add::type { return *x+fc::forward(u); } template auto operator - ( const fwd& x, U&& u ) -> typename detail::sub::type { return *x-fc::forward(u); } template auto operator << ( U& u, const fwd& f ) -> typename detail::insert_op::type { return u << *f; } template auto operator >> ( U& u, fwd& f ) -> typename detail::extract_op::type { return u >> *f; } template bool fwd::operator !()const { return !(**this); } template void check_size() { static_assert( (ProvidedSize >= RequiredSize), "Failed to reserve enough space in fc::fwd" ); } template template fwd::fwd( U&& u ) { check_size(); new (this) T( fc::forward(u) ); } template template fwd::fwd( U&& u, V&& v ) { check_size(); new (this) T( fc::forward(u), fc::forward(v) ); } template template fwd::fwd( U&& u, V&& v, X&& x, Y&& y ) { check_size(); new (this) T( fc::forward(u), fc::forward(v), fc::forward(x), fc::forward(y) ); } template fwd::fwd() { check_size(); new (this) T; } template fwd::fwd( const fwd& f ){ check_size(); new (this) T( *f ); } template fwd::fwd( fwd&& f ){ check_size(); new (this) T( fc::move(*f) ); } template fwd::operator T&() { return *(( T*)this); } template fwd::operator const T&()const { return *((const T*)this); } template T& fwd::operator*() { return *((T*)this); } template const T& fwd::operator*()const { return *((const T*)this); } template const T* fwd::operator->()const { return ((const T*)this); } template T* fwd::operator->(){ return ((T*)this); } template fwd::~fwd() { ((T*)this)->~T(); } template template T& fwd::operator = ( U&& u ) { return **this = fc::forward(u); } template T& fwd::operator = ( fwd&& u ) { return **this = fc::move(*u); } template T& fwd::operator = ( const fwd& u ) { return **this = *u; } } // namespace fc