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) );
|
|
|
|
|
}
|
2012-09-18 03:04:42 +00:00
|
|
|
|
|
|
|
|
template<typename T,unsigned int S,typename A>
|
|
|
|
|
template<typename U,typename V>
|
|
|
|
|
fwd<T,S,A>::fwd( U&& u, V&& v ) {
|
|
|
|
|
check_size<sizeof(T),sizeof(_store)>();
|
|
|
|
|
new (this) T( fc::forward<U>(u), fc::forward<V>(v) );
|
|
|
|
|
}
|
|
|
|
|
template<typename T,unsigned int S,typename A>
|
|
|
|
|
template<typename U,typename V,typename X,typename Y>
|
|
|
|
|
fwd<T,S,A>::fwd( U&& u, V&& v, X&& x, Y&& y ) {
|
|
|
|
|
check_size<sizeof(T),sizeof(_store)>();
|
|
|
|
|
new (this) T( fc::forward<U>(u), fc::forward<V>(v), fc::forward<X>(x), fc::forward<Y>(y) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-09-08 02:50:37 +00:00
|
|
|
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_
|