#include "Luau/NotNull.h"
#include "doctest.h"
#include <stdio.h>
#include <unordered_map>
#include <string>
using Luau::NotNull;
static_assert(!std::is_convertible<NotNull<int>, bool>::value, "NotNull<T> ought not to be convertible into bool");
namespace
{
struct Test
{
int x;
float y;
static int count;
Test()
{
++count;
}
~Test()
{
--count;
}
};
int Test::count = 0;
}
int foo(NotNull<int> p)
{
return *p;
}
void bar(int* q) {}
TEST_SUITE_BEGIN("NotNull");
TEST_CASE("basic_stuff")
{
NotNull<int> a = NotNull{new int(55)};
NotNull<int> b{new int(55)};
NotNull<int> d = a;
int e = *d;
*d = 1;
CHECK(e == 55);
const NotNull<int> f = d;
*f = 5;
CHECK_EQ(a, d);
CHECK(a != b);
NotNull<const int> g(a);
CHECK(g == a);
(void)f;
NotNull<Test> t{new Test};
t->x = 5;
t->y = 3.14f;
const NotNull<Test> u = t;
u->x = 44;
int v = u->x;
CHECK(v == 44);
bar(a);
delete a;
delete b;
delete t;
CHECK_EQ(0, Test::count);
}
TEST_CASE("hashable")
{
std::unordered_map<NotNull<int>, const char*> map;
int a_ = 8;
int b_ = 10;
NotNull<int> a{&a_};
NotNull<int> b{&b_};
std::string hello = "hello";
std::string world = "world";
map[a] = hello.c_str();
map[b] = world.c_str();
CHECK_EQ(2, map.size());
CHECK_EQ(hello.c_str(), map[a]);
CHECK_EQ(world.c_str(), map[b]);
}
TEST_CASE("const")
{
int p = 0;
int q = 0;
NotNull<int> n{&p};
*n = 123;
NotNull<const int> m = n;
CHECK(123 == *m);
NotNull<int> n2{&q};
m = n2;
const NotNull<int> m2 = n;
*m2 = 321;
CHECK(321 == *n);
}
TEST_CASE("const_compatibility")
{
int* raw = new int(8);
NotNull<int> a(raw);
NotNull<const int> b(raw);
NotNull<const int> c = a;
CHECK_EQ(*c, 8);
delete raw;
}
TEST_SUITE_END();