#pragma once #include #include #include namespace fc { namespace detail { 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 << ( U& u, const smart_ref& f ) -> typename detail::insert_op::type { return u << *f; } template auto operator >> ( U& u, smart_ref& f ) -> typename detail::extract_op::type { return u >> *f; } template bool smart_ref::operator !()const { return !(**this); } template template smart_ref::smart_ref( U&& u ) { impl = new (this) T( fc::forward(u) ); } template template smart_ref::smart_ref( U&& u, V&& v ) { impl = new T( fc::forward(u), fc::forward(v) ); } template template smart_ref::smart_ref( U&& u, V&& v, X&& x, Y&& y ) { impl = new T( fc::forward(u), fc::forward(v), fc::forward(x), fc::forward(y) ); } template smart_ref::smart_ref() { impl = new T; } template smart_ref::smart_ref( const smart_ref& f ){ impl = new T( *f ); } template smart_ref::smart_ref( smart_ref&& f ){ impl = new T( fc::move(*f) ); } template smart_ref::operator T&() { return *impl; } template smart_ref::operator const T&()const { return *impl; } template T& smart_ref::operator*() { return *impl; } template const T& smart_ref::operator*()const { return *impl; } template const T* smart_ref::operator->()const { return impl; } template T* smart_ref::operator->(){ return impl; } template smart_ref::~smart_ref() { delete impl; } template template T& smart_ref::operator = ( U&& u ) { return **this = fc::forward(u); } template T& smart_ref::operator = ( smart_ref&& u ) { if( &u == this ) return *impl; delete impl; impl = u.impl; u.impl = nullptr; return *impl; } template T& smart_ref::operator = ( const smart_ref& u ) { if( &u == this ) return *impl; return **this = *u; } } // namespace fc