adding missing smart_ref files

This commit is contained in:
Daniel Larimer 2015-07-09 13:39:55 -04:00
parent 935e90c1ec
commit 2ef7583f90
2 changed files with 146 additions and 0 deletions

View file

@ -0,0 +1,41 @@
#pragma once
namespace fc {
/**
* @brief Used to forward declare value types and break circular dependencies or use heap allocation
*
* A smart reference is heap allocated, move-aware, and is gauranteed to never be null (except after a move)
*/
template<typename T>
class smart_ref {
public:
template<typename U> smart_ref( U&& u );
template<typename U, typename V> smart_ref( U&& u, V&& v );
template<typename U, typename V, typename X, typename Y> smart_ref( U&& u, V&& v, X&&, Y&& );
smart_ref();
smart_ref( const smart_ref& f );
smart_ref( smart_ref&& f );
operator const T&()const;
operator T&();
T& operator*();
const T& operator*()const;
const T* operator->()const;
T* operator->();
bool operator !()const;
template<typename U>
T& operator = ( U&& u );
T& operator = ( smart_ref&& u );
T& operator = ( const smart_ref& u );
~smart_ref();
private:
T* impl;
};
}

View file

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