This commit is contained in:
Treb Connell 2015-09-24 18:02:37 -07:00
parent 8ae77b1fd5
commit 35fb11853f
2 changed files with 24 additions and 5 deletions

View File

@ -162,7 +162,11 @@ private:
template<class T> template<class T>
class maybe_null_dbg class maybe_null_dbg
{ {
template<class U>
friend class maybe_null_dbg;
public: public:
static_assert(std::is_constructible<T, std::nullptr_t>::value, "maybe_null's template parameter must be constructible from nullptr");
maybe_null_dbg() : ptr_(nullptr), tested_(false) {} maybe_null_dbg() : ptr_(nullptr), tested_(false) {}
maybe_null_dbg(const T& p) : ptr_(p), tested_(false) {} maybe_null_dbg(const T& p) : ptr_(p), tested_(false) {}
@ -202,8 +206,10 @@ public:
bool operator==(const T& rhs) const { tested_ = true; return ptr_ == rhs; } bool operator==(const T& rhs) const { tested_ = true; return ptr_ == rhs; }
bool operator!=(const T& rhs) const { return !(*this == rhs); } bool operator!=(const T& rhs) const { return !(*this == rhs); }
bool operator==(const maybe_null_dbg& rhs) const { tested_ = true; rhs.tested_ = true; return ptr_ == rhs.ptr_; } template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
bool operator!=(const maybe_null_dbg& rhs) const { return !(*this == rhs); } bool operator==(const maybe_null_dbg<U>& rhs) const { tested_ = true; rhs.tested_ = true; return ptr_ == rhs.ptr_; }
template <typename U, typename Dummy = std::enable_if_t<std::is_convertible<U, T>::value>>
bool operator!=(const maybe_null_dbg<U>& rhs) const { return !(*this == rhs); }
T get() const { T get() const {
fail_fast_assert(tested_); fail_fast_assert(tested_);
@ -217,8 +223,6 @@ public:
T operator->() const { return get(); } T operator->() const { return get(); }
private: private:
const size_t ptee_size_ = sizeof(*ptr_); // T must be a pointer type
// unwanted operators...pointers only point to single objects! // unwanted operators...pointers only point to single objects!
// TODO ensure all arithmetic ops on this type are unavailable // TODO ensure all arithmetic ops on this type are unavailable
maybe_null_dbg<T>& operator++() = delete; maybe_null_dbg<T>& operator++() = delete;
@ -238,6 +242,8 @@ template<class T>
class maybe_null_ret class maybe_null_ret
{ {
public: public:
static_assert(std::is_constructible<T, std::nullptr_t>::value, "maybe_null's template parameter must be constructible from nullptr");
maybe_null_ret() : ptr_(nullptr) {} maybe_null_ret() : ptr_(nullptr) {}
maybe_null_ret(std::nullptr_t) : ptr_(nullptr) {} maybe_null_ret(std::nullptr_t) : ptr_(nullptr) {}
maybe_null_ret(const T& p) : ptr_(p) {} maybe_null_ret(const T& p) : ptr_(p) {}
@ -280,7 +286,6 @@ private:
maybe_null_ret<T>& operator-(size_t) = delete; maybe_null_ret<T>& operator-(size_t) = delete;
maybe_null_ret<T>& operator-=(size_t) = delete; maybe_null_ret<T>& operator-=(size_t) = delete;
const size_t ptee_size_ = sizeof(*ptr_); // T must be a pointer type
T ptr_; T ptr_;
}; };

View File

@ -241,6 +241,20 @@ SUITE(MaybeNullTests)
// Make sure we no longer throw here // Make sure we no longer throw here
CHECK(p1.get() != nullptr); CHECK(p1.get() != nullptr);
} }
TEST(TestMaybeNullPtrT)
{
maybe_null<std::nullptr_t> p1;
maybe_null<std::nullptr_t> p2;
CHECK_THROW(p1.get(), fail_fast);
CHECK(p1 == p2);
// Make sure we no longer throw here
CHECK(p1.get() == nullptr);
CHECK(p2.get() == nullptr);
}
} }
int main(int, const char *[]) int main(int, const char *[])