Skip to content

Instantly share code, notes, and snippets.

@fpelliccioni
Created December 16, 2012 20:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fpelliccioni/4312663 to your computer and use it in GitHub Desktop.
Save fpelliccioni/4312663 to your computer and use it in GitHub Desktop.
C++ Safe Dereferencing Nullable References Proposal
#include <memory>
#include <cstddef> //std::nullptr_t;
template <typename T>
class safe_ref
{
public:
typedef T type;
typedef T& reference;
explicit safe_ref( std::nullptr_t )
: t_( nullptr )
{}
explicit safe_ref()
: t_( nullptr )
{}
explicit safe_ref(T& t)
: t_( std::addressof(t) )
{}
template < typename Y >
explicit safe_ref( Y& t )
: t_( std::addressof(t) )
{}
template < typename Y >
safe_ref( safe_ref<Y> const& r )
: t_( r.t_ )
{}
template <typename Func>
void use ( Func f ) const
{
T* local_ptr = t_;
if ( local_ptr != nullptr )
{
f( *t_ ); //side note: how to know if f(...) is const?
}
}
template <typename Func, typename FuncElse>
void use ( Func f, FuncElse fe ) const
{
T* local_ptr = t_;
if ( local_ptr != nullptr )
{
f( *t_ ); //side note: how to know if f(...) is const?
}
else
{
fe();
}
}
safe_ref& operator=( std::nullptr_t )
{
t_ = nullptr;
}
safe_ref& operator=( T& t )
{
t_ = std::addressof(t);
}
private:
bool is_initialized() const
{
return t_ != nullptr;
}
private:
template <typename Y> friend class safe_ref;
T* t_;
};
template <typename T>
inline safe_ref<T> const ref(T& t)
{
return safe_ref<T>(t);
}
template <typename T>
inline safe_ref<T const> const cref(T const& t)
{
return safe_ref<T const>(t);
}
#define IF(_local_, _ref_, _if_code_, _else_code_) \
_ref_.use( [&] ( typename decltype(_ref_)::reference _local_ ) { \
_if_code_ \
}, \
[&] { \
_else_code_ \
});
//----------------------------------------------------------------------------
// Usage
//----------------------------------------------------------------------------
#include <iostream>
#include <string>
struct A
{
void doit() const
{
std::cout << "A::doit: " << i_ << "\n";
}
int i_ = 99;
};
void f( safe_ref<A> ref )
{
IF( local, ref,
{
local.doit();
},
{
std::cout << "is nullptr\n";
})
}
int main()
{
A a;
safe_ref<A> r;
f(r);
r = a;
f(r);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment