peerplays-fc/include/fc/fwd_impl.hpp

123 lines
4.1 KiB
C++
Raw Normal View History

2012-09-08 02:50:37 +00:00
#ifndef _FC_FWD_IMPL_HPP_
#define _FC_FWD_IMPL_HPP_
#include <fc/utility.hpp>
#include <fc/fwd.hpp>
#include <new>
namespace fc {
namespace detail {
template<typename A, typename U>
struct add {
typedef decltype( *((A*)0) + *((typename fc::remove_reference<U>::type*)0) ) type;
};
template<typename A, typename U>
struct add_eq {
typedef decltype( *((A*)0) += *((typename fc::remove_reference<U>::type*)0) ) type;
};
template<typename A, typename U>
struct sub {
typedef decltype( *((A*)0) - *((typename fc::remove_reference<U>::type*)0) ) type;
};
template<typename A, typename U>
struct sub_eq {
typedef decltype( *((A*)0) -= *((typename fc::remove_reference<U>::type*)0) ) type;
};
template<typename A, typename U>
struct insert_op {
typedef decltype( *((A*)0) << *((typename fc::remove_reference<U>::type*)0) ) type;
};
template<typename A, typename U>
struct extract_op {
A* a;
U* u;
typedef decltype( *a >> *u ) type;
};
}
template<typename T, unsigned int S, typename U, typename A>
auto operator + ( const fwd<T,S,A>& x, U&& u ) -> typename detail::add<T,U>::type { return *x+fc::forward<U>(u); }
template<typename T, unsigned int S, typename U, typename A>
auto operator - ( const fwd<T,S,A>& x, U&& u ) -> typename detail::sub<T,U>::type { return *x-fc::forward<U>(u); }
template<typename T, unsigned int S, typename U, typename A>
auto operator << ( U& u, const fwd<T,S,A>& f ) -> typename detail::insert_op<U,T>::type { return u << *f; }
template<typename T, unsigned int S, typename U, typename A>
auto operator >> ( U& u, fwd<T,S,A>& f ) -> typename detail::extract_op<U,T>::type { return u >> *f; }
template<typename T, unsigned int S, typename A>
bool fwd<T,S,A>::operator !()const { return !(**this); }
2012-09-09 03:46:19 +00:00
template<uint64_t RequiredSize, uint64_t ProvidedSize>
void check_size() { static_assert( (ProvidedSize >= RequiredSize), "Failed to reserve enough space in fc::fwd<T,S>" ); }
2012-09-08 02:50:37 +00:00
template<typename T,unsigned int S,typename A>
template<typename U>
fwd<T,S,A>::fwd( U&& u ) {
2012-09-09 03:46:19 +00:00
check_size<sizeof(T),sizeof(_store)>();
2012-09-08 02:50:37 +00:00
new (this) T( fc::forward<U>(u) );
}
template<typename T,unsigned int S,typename A>
fwd<T,S,A>::fwd() {
2012-09-09 03:46:19 +00:00
check_size<sizeof(T),sizeof(_store)>();
2012-09-08 02:50:37 +00:00
new (this) T();
}
template<typename T,unsigned int S,typename A>
fwd<T,S,A>::fwd( const fwd<T,S,A>& f ){
2012-09-09 03:46:19 +00:00
check_size<sizeof(T),sizeof(_store)>();
2012-09-08 02:50:37 +00:00
new (this) T( *f );
}
template<typename T,unsigned int S,typename A>
fwd<T,S,A>::fwd( fwd<T,S,A>&& f ){
2012-09-09 03:46:19 +00:00
check_size<sizeof(T),sizeof(_store)>();
2012-09-08 02:50:37 +00:00
new (this) T( fc::move(*f) );
}
template<typename T,unsigned int S, typename A>
fwd<T,S,A>::operator T&() { return *(( T*)this); }
template<typename T,unsigned int S, typename A>
fwd<T,S,A>::operator const T&()const { return *((const T*)this); }
template<typename T,unsigned int S, typename A>
T& fwd<T,S,A>::operator*() { return *((T*)this); }
template<typename T,unsigned int S, typename A>
const T& fwd<T,S,A>::operator*()const { return *((const T*)this); }
template<typename T,unsigned int S, typename A>
const T* fwd<T,S,A>::operator->()const { return ((const T*)this); }
template<typename T,unsigned int S, typename A>
T* fwd<T,S,A>::operator->(){ return ((T*)this); }
template<typename T,unsigned int S, typename A>
fwd<T,S,A>::~fwd() {
((T*)this)->~T();
}
template<typename T,unsigned int S, typename A>
template<typename U>
T& fwd<T,S,A>::operator = ( U&& u ) {
return **this = fc::forward<U>(u);
}
template<typename T,unsigned int S, typename A>
T& fwd<T,S,A>::operator = ( fwd<T,S,A>&& u ) {
return **this = fc::move(*u);
}
template<typename T,unsigned int S, typename A>
T& fwd<T,S,A>::operator = ( const fwd<T,S,A>& u ) {
return **this = *u;
}
} // namespace fc
#endif //_FC_FWD_IMPL_HPP_