Merge pull request #70 from kernhanda/kernhanda/not_maybe_null

not_null and maybe_null variants should only work on nullptr-assignable types.
This commit is contained in:
Neil MacIntosh 2015-09-27 12:43:44 -07:00
commit bad8545eee
3 changed files with 24 additions and 0 deletions

View File

@ -108,6 +108,7 @@ typename Cont::value_type& at(Cont& cont, size_t index) { fail_fast_assert(index
template<class T> template<class T>
class not_null class not_null
{ {
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
public: public:
not_null(T t) : ptr_(t) { ensure_invariant(); } not_null(T t) : ptr_(t) { ensure_invariant(); }
@ -168,6 +169,7 @@ private:
template<class T> template<class T>
class maybe_null_dbg class maybe_null_dbg
{ {
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
public: public:
maybe_null_dbg() : ptr_(nullptr), tested_(false) {} maybe_null_dbg() : ptr_(nullptr), tested_(false) {}
@ -243,6 +245,7 @@ private:
template<class T> template<class T>
class maybe_null_ret class maybe_null_ret
{ {
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");
public: public:
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) {}

View File

@ -16,6 +16,7 @@
#include <UnitTest++/UnitTest++.h> #include <UnitTest++/UnitTest++.h>
#include <gsl.h> #include <gsl.h>
#include <vector>
using namespace Guide; using namespace Guide;
@ -27,12 +28,24 @@ SUITE(MaybeNullTests)
{ {
TEST(TestMaybeNull1) TEST(TestMaybeNull1)
{ {
#ifdef CONFIRM_COMPILATION_ERRORS
// Forbid non-nullptr assignable types
maybe_null_ret<std::vector<int>> f_ret(std::vector<int>{1});
maybe_null_ret<std::vector<int>> f_ret(std::vector<int>{1});
maybe_null_ret<int> z_ret(10);
maybe_null_dbg<std::vector<int>> y_dbg({1,2});
maybe_null_dbg<int> z_dbg(10);
maybe_null_dbg<std::vector<int>> y_dbg({1,2});
#endif
int n = 5; int n = 5;
maybe_null_dbg<int *> opt_n(&n); maybe_null_dbg<int *> opt_n(&n);
int result = 0; int result = 0;
bool threw = false; bool threw = false;
CHECK_THROW(result = *opt_n, fail_fast); CHECK_THROW(result = *opt_n, fail_fast);
maybe_null_ret<std::shared_ptr<int>> x_ret(std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
maybe_null_dbg<std::shared_ptr<int>> x_dbg(std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
} }
TEST(TestMaybeNull2) TEST(TestMaybeNull2)

View File

@ -16,6 +16,7 @@
#include <UnitTest++/UnitTest++.h> #include <UnitTest++/UnitTest++.h>
#include <gsl.h> #include <gsl.h>
#include <vector>
using namespace Guide; using namespace Guide;
@ -48,11 +49,18 @@ SUITE(NotNullTests)
not_null<int*> p; // yay...does not compile! not_null<int*> p; // yay...does not compile!
std::unique_ptr<int> up = std::make_unique<int>(120); std::unique_ptr<int> up = std::make_unique<int>(120);
not_null<int*> p = up; not_null<int*> p = up;
// Forbid non-nullptr assignable types
not_null<std::vector<int>> f(std::vector<int>{1});
not_null<int> z(10);
not_null<std::vector<int>> y({1,2});
#endif #endif
int i = 12; int i = 12;
auto rp = RefCounted<int>(&i); auto rp = RefCounted<int>(&i);
not_null<int*> p(rp); not_null<int*> p(rp);
CHECK(p.get() == &i); CHECK(p.get() == &i);
not_null<std::shared_ptr<int>> x(std::make_shared<int>(10)); // shared_ptr<int> is nullptr assignable
} }
TEST(TestNotNullCasting) TEST(TestNotNullCasting)