//==============================================================================
ANKI_TEST(Resource, ResourceFilesystem)
{
	printf("Test requires the data dir\n");

	HeapAllocator<U8> alloc(allocAligned, nullptr);
	ResourceFilesystem fs(alloc);

	{
		ANKI_TEST_EXPECT_NO_ERR(fs.addNewPath("data/dir/../dir/"));
		ResourceFilePtr file;
		ANKI_TEST_EXPECT_NO_ERR(fs.openFile("subdir0/hello.txt", file));
		StringAuto txt(alloc);
		ANKI_TEST_EXPECT_NO_ERR(file->readAllText(alloc, txt));
		ANKI_TEST_EXPECT_EQ(txt, "hello\n");
	}

	{
		ANKI_TEST_EXPECT_NO_ERR(fs.addNewPath("./data/dir.ankizip"));
		ResourceFilePtr file;
		ANKI_TEST_EXPECT_NO_ERR(fs.openFile("subdir0/hello.txt", file));
		StringAuto txt(alloc);
		ANKI_TEST_EXPECT_NO_ERR(file->readAllText(alloc, txt));
		ANKI_TEST_EXPECT_EQ(txt, "hell\n");
	}
}
Esempio n. 2
0
//==============================================================================
ANKI_TEST(Util, Thread)
{
	static const char* THREAD_NAME = "name";
	Thread t(THREAD_NAME);

	static const U64 NUMBER = 0xFAFAFAFABABABA;
	U64 u = NUMBER;

	t.start(&u, [](Thread::Info& info) -> Error
	{
		Bool check = true; 
		
		// Check name
		check = check && (std::strcmp(info.m_threadName, THREAD_NAME) == 0);

		// Check user value
		U64& num = *reinterpret_cast<U64*>(info.m_userData);
		check = check && (num == NUMBER);

		// Change number
		num = 0xF00;

		HighRezTimer::sleep(1.0);

		return (check != true) ? ErrorCode::FUNCTION_FAILED : ErrorCode::NONE;
	});


	Error err = t.join();
	ANKI_TEST_EXPECT_EQ(err, 0);
	ANKI_TEST_EXPECT_EQ(u, 0xF00);
}
Esempio n. 3
0
ANKI_TEST(Memory, ChainMemoryPool)
{
	// Basic test
	{
		const U size = 8;
		ChainMemoryPool pool;

		Error error = pool.create(
			allocAligned, nullptr,
			size, size + 1, 
			ChainMemoryPool::ChunkGrowMethod::MULTIPLY, 2, 1);
		ANKI_TEST_EXPECT_EQ(error, ErrorCode::NONE);

		void* mem = pool.allocate(5, 1);
		ANKI_TEST_EXPECT_NEQ(mem, nullptr);

		void* mem1 = pool.allocate(5, 1);
		ANKI_TEST_EXPECT_NEQ(mem1, nullptr);

		pool.free(mem1);
		pool.free(mem);
		ANKI_TEST_EXPECT_EQ(pool.getChunksCount(), 0);
	}

	// Basic test 2
	{
		const U size = sizeof(PtrSize) + 10;
		ChainMemoryPool pool;
		
		Error error = pool.create(
			allocAligned, nullptr,
			size, size * 2, 
			ChainMemoryPool::ChunkGrowMethod::MULTIPLY, 2, 1);
		ANKI_TEST_EXPECT_EQ(error, ErrorCode::NONE);

		void* mem = pool.allocate(size, 1);
		ANKI_TEST_EXPECT_NEQ(mem, nullptr);

		void* mem1 = pool.allocate(size, 1);
		ANKI_TEST_EXPECT_NEQ(mem1, nullptr);

		void* mem3 = pool.allocate(size, 1);
		ANKI_TEST_EXPECT_NEQ(mem1, nullptr);

		pool.free(mem1);

		mem1 = pool.allocate(size, 1);
		ANKI_TEST_EXPECT_NEQ(mem1, nullptr);

		pool.free(mem3);
		pool.free(mem1);
		pool.free(mem);

		ANKI_TEST_EXPECT_EQ(pool.getChunksCount(), 0);
	}
}
Esempio n. 4
0
ANKI_TEST(Allocators, StackAllocator)
{
	Foo::reset();

	// With simple string
	{
		StackAllocator<char, false> alloc(
			StackMemoryPool(allocAligned, nullptr, 128));
		typedef std::basic_string<char, std::char_traits<char>, 
			StackAllocator<char, false>> Str;

		Str str(alloc);

		str = "lalala";
		str = "lalalalo";
	}

	// With vector
	{
		typedef StackAllocator<Foo, false> All;
		All alloc(StackMemoryPool(allocAligned, nullptr, 
			(sizeof(Foo) + 1) * 10, 1));
		std::vector<Foo, All> vec(alloc);

		vec.reserve(10);

		U sumi = 0;
		for(U i = 0; i < 10; i++)
		{
			std::cout << "pushing" << std::endl;
			vec.push_back(Foo(10 * i));
			sumi += 10 * i;
		}

		U sum = 0;

		for(const Foo& foo : vec)
		{
			sum += foo.x;
		}

		ANKI_TEST_EXPECT_EQ(sum, sumi);
	}

	ANKI_TEST_EXPECT_EQ(Foo::constructorCallCount, 
		Foo::destructorCallCount);

	// End
	Foo::reset();
}
Esempio n. 5
0
ANKI_TEST(Util, Threadpool)
{
	const U32 threadsCount = 4;
	const U32 repeat = 5;
	Threadpool* tp = new Threadpool(threadsCount);

	TestJobTP jobs[threadsCount];

	for(U32 i = 1; i < repeat; i++)
	{
		U32 iterations = rand() % 100000;

		for(U32 j = 0; j < threadsCount; j++)
		{
			jobs[j].in = i;
			jobs[j].iterations = iterations;

			tp->assignNewTask(j, &jobs[j]);
		}

		ANKI_TEST_EXPECT_NO_ERR(tp->waitForAllThreadsToFinish());

		for(U32 j = 0; j < threadsCount; j++)
		{
			ANKI_TEST_EXPECT_EQ(jobs[j].in, i + iterations);
		}
	}

	delete tp;
}
Esempio n. 6
0
//==============================================================================
ANKI_TEST(Util, Mutex)
{
	Thread t0(nullptr), t1(nullptr);
	Mutex mtx;

	static const U ITERATIONS = 1000000;

	class In
	{
	public:
		I64 m_num = ITERATIONS;
		Mutex* m_mtx;
	};

	In in;
	in.m_mtx = &mtx;

	t0.start(&in, [](Thread::Info& info) -> Error
	{
		In& in = *reinterpret_cast<In*>(info.m_userData);
		I64& num = in.m_num;
		Mutex& mtx = *in.m_mtx;

		for(U i = 0; i < ITERATIONS; i++)
		{
			mtx.lock();
			num += 2;
			mtx.unlock();
		}

		return ErrorCode::NONE;
	});

	t1.start(&in, [](Thread::Info& info) -> Error
	{
		In& in = *reinterpret_cast<In*>(info.m_userData);
		I64& num = in.m_num;
		Mutex& mtx = *in.m_mtx;

		for(U i = 0; i < ITERATIONS; i++)
		{
			mtx.lock();
			--num;
			mtx.unlock();
		}

		return ErrorCode::NONE;
	});


	ANKI_TEST_EXPECT_NO_ERR(t0.join());
	ANKI_TEST_EXPECT_NO_ERR(t1.join());

	ANKI_TEST_EXPECT_EQ(in.m_num, ITERATIONS * 2);
}
Esempio n. 7
0
ANKI_TEST(Gr, Buffer)
{
	COMMON_BEGIN()

	BufferPtr a = gr->newInstance<Buffer>(512, BufferUsageBit::UNIFORM_ALL, BufferMapAccessBit::NONE);

	BufferPtr b =
		gr->newInstance<Buffer>(64, BufferUsageBit::STORAGE_ALL, BufferMapAccessBit::WRITE | BufferMapAccessBit::READ);

	void* ptr = b->map(0, 64, BufferMapAccessBit::WRITE);
	ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
	U8 ptr2[64];
	memset(ptr, 0xCC, 64);
	memset(ptr2, 0xCC, 64);
	b->unmap();

	ptr = b->map(0, 64, BufferMapAccessBit::READ);
	ANKI_TEST_EXPECT_NEQ(ptr, nullptr);
	ANKI_TEST_EXPECT_EQ(memcmp(ptr, ptr2, 64), 0);
	b->unmap();

	COMMON_END()
}
ANKI_TEST(Resource, ResourceManager)
{
    // Create
    Config config;

    HeapAllocator<U8> alloc(allocAligned, nullptr);

    ResourceManagerInitInfo rinit;
    rinit.m_gr = nullptr;
    rinit.m_config = &config;
    rinit.m_cacheDir = "/tmp/";
    rinit.m_allocCallback = allocAligned;
    rinit.m_allocCallbackData = nullptr;
    ResourceManager* resources = alloc.newInstance<ResourceManager>();
    ANKI_TEST_EXPECT_NO_ERR(resources->create(rinit));

    // Very simple
    {
        DummyResourcePtr a;
        ANKI_TEST_EXPECT_NO_ERR(resources->loadResource("blah", a));
    }

    // Load a resource
    {
        DummyResourcePtr a;

        ANKI_TEST_EXPECT_NO_ERR(resources->loadResource("blah", a));

        {
            DummyResourcePtr b = a;
            a = b;
            b = a;
        }
    }

    // Load and load again
    {
        DummyResourcePtr a;
        ANKI_TEST_EXPECT_NO_ERR(resources->loadResource("blah", a));
        auto refcount = a->getRefcount().load();

        DummyResourcePtr b;
        ANKI_TEST_EXPECT_NO_ERR(resources->loadResource("blah", b));
        ANKI_TEST_EXPECT_EQ(b->getRefcount().load(), a->getRefcount().load());
        ANKI_TEST_EXPECT_EQ(a->getRefcount().load(), refcount + 1);

        ANKI_TEST_EXPECT_EQ(b.get(), a.get());

        // Again
        DummyResourcePtr c;
        ANKI_TEST_EXPECT_NO_ERR(resources->loadResource("blah", c));
        ANKI_TEST_EXPECT_EQ(a->getRefcount().load(), refcount + 2);

        // Load something else
        DummyResourcePtr d;
        ANKI_TEST_EXPECT_NO_ERR(resources->loadResource("blih", d));
        ANKI_TEST_EXPECT_EQ(a->getRefcount().load(), refcount + 2);
    }

    // Error
    {
        {
            DummyResourcePtr a;
            ANKI_TEST_EXPECT_EQ(resources->loadResource("error", a), ErrorCode::USER_DATA);
        }

        {
            DummyResourcePtr a;
            ANKI_TEST_EXPECT_EQ(resources->loadResource("error", a), ErrorCode::USER_DATA);
        }
    }

    // Delete
    alloc.deleteInstance(resources);
}
ANKI_TEST(Util, DynamicArray)
{
	{
		HeapAllocator<U8> alloc(allocAligned, nullptr);
		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);

		arr.resize(0);
		arr.resize(2, 1);
		arr.resize(3, 2);
		arr.resize(4, 3);

		ANKI_TEST_EXPECT_EQ(arr.getSize(), 4);
		ANKI_TEST_EXPECT_EQ(arr[0].m_x, 1);
		ANKI_TEST_EXPECT_EQ(arr[1].m_x, 1);
		ANKI_TEST_EXPECT_EQ(arr[2].m_x, 2);
		ANKI_TEST_EXPECT_EQ(arr[3].m_x, 3);

		arr.emplaceBack(4);
		ANKI_TEST_EXPECT_EQ(arr.getSize(), 5);
		ANKI_TEST_EXPECT_EQ(arr[4].m_x, 4);

		arr.resize(1);
		arr.resize(0);
	}

	// Fuzzy
	{
		srand(time(nullptr));
		HeapAllocator<U8> alloc(allocAligned, nullptr);
		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);

		std::vector<DynamicArrayFoo> vec;

		const U ITERATIONS = 1000000;

		for(U i = 0; i < ITERATIONS; ++i)
		{
			const Bool grow = arr.getSize() > 0 && (rand() & 1);
			PtrSize newSize;
			U32 value = rand();
			if(grow)
			{
				newSize = vec.size() * randRange(1.0, 4.0);
			}
			else
			{
				newSize = vec.size() * randRange(0.0, 0.9);
			}

			vec.resize(newSize, value);
			arr.resize(newSize, value);

			// Validate
			ANKI_TEST_EXPECT_EQ(arr.getSize(), vec.size());
			for(U i = 0; i < arr.getSize(); ++i)
			{
				ANKI_TEST_EXPECT_EQ(arr[i].m_x, vec[i].m_x);
			}

			arr.validate();
		}

		arr = DynamicArrayAuto<DynamicArrayFoo>(alloc);
		vec = std::vector<DynamicArrayFoo>();
		ANKI_TEST_EXPECT_GT(destructorCount, 0);
		ANKI_TEST_EXPECT_EQ(
			constructor0Count + constructor1Count + constructor2Count + constructor3Count, destructorCount);
	}
}
Esempio n. 10
0
ANKI_TEST(Util, DynamicArrayEmplaceAt)
{
	HeapAllocator<U8> alloc(allocAligned, nullptr);

	// Empty & add to the end
	{
		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);

		arr.emplaceAt(arr.getEnd(), 12);
		ANKI_TEST_EXPECT_EQ(arr[0].m_x, 12);
	}

	// 1 element & add to he end
	{
		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);
		arr.emplaceBack(12);

		arr.emplaceAt(arr.getEnd(), 34);

		ANKI_TEST_EXPECT_EQ(arr[0].m_x, 12);
		ANKI_TEST_EXPECT_EQ(arr[1].m_x, 34);
	}

	// 1 element & add to 0
	{
		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);
		arr.emplaceBack(12);

		arr.emplaceAt(arr.getBegin(), 34);

		ANKI_TEST_EXPECT_EQ(arr[0].m_x, 34);
		ANKI_TEST_EXPECT_EQ(arr[1].m_x, 12);
	}

	// A bit more complex
	{
		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);

		for(U i = 0; i < 10; ++i)
		{
			arr.emplaceBack(i);
		}

		arr.emplaceAt(arr.getBegin() + 4, 666);

		for(I i = 0; i < 10 + 1; ++i)
		{
			if(i < 4)
			{
				ANKI_TEST_EXPECT_EQ(arr[i].m_x, i);
			}
			else if(i == 4)
			{
				ANKI_TEST_EXPECT_EQ(arr[i].m_x, 666);
			}
			else
			{
				ANKI_TEST_EXPECT_EQ(arr[i].m_x, i - 1);
			}
		}
	}

	// Fuzzy
	{
		srand(time(nullptr));

		DynamicArrayAuto<DynamicArrayFoo> arr(alloc);
		std::vector<DynamicArrayFoo> vec;

		const I ITERATIONS = 10000;
		for(I i = 0; i < ITERATIONS; ++i)
		{
			I randNum = rand();
			I op = rand() % 3;

			switch(op)
			{
			case 0:
				// Push back
				arr.emplaceBack(randNum);
				vec.emplace_back(randNum);
				break;
			case 1:
				// Insert somewhere
				if(!arr.isEmpty())
				{
					I pos = rand() % arr.getSize();
					arr.emplaceAt(arr.getBegin() + pos, randNum);
					vec.emplace(vec.begin() + pos, randNum);
				}
				break;
			default:
				// Insert at the end
				arr.emplaceAt(arr.getEnd(), randNum);
				vec.emplace(vec.end(), randNum);
				break;
			}
		}

		// Check
		ANKI_TEST_EXPECT_EQ(arr.getSize(), vec.size());
		for(PtrSize i = 0; i < arr.getSize(); ++i)
		{
			ANKI_TEST_EXPECT_EQ(arr[i].m_x, vec[i].m_x);
		}

		arr.destroy();
		vec.resize(0);

		ANKI_TEST_EXPECT_EQ(
			constructor0Count + constructor1Count + constructor2Count + constructor3Count, destructorCount);
	}
}
Esempio n. 11
0
//==============================================================================
ANKI_TEST(Resource, AsyncLoader)
{
	HeapAllocator<U8> alloc(allocAligned, nullptr);

	// Simple create destroy
	{
		AsyncLoader a;
		a.init(alloc);
	}

	// Simple task that will finish
	{
		AsyncLoader a;
		a.init(alloc);
		Barrier barrier(2);

		a.submitNewTask<Task>(0.0, &barrier, nullptr);
		barrier.wait();
	}

	// Many tasks that will finish
	{
		AsyncLoader a;
		a.init(alloc);
		Barrier barrier(2);
		Atomic<U32> counter = {0};
		const U COUNT = 100;

		for(U i = 0; i < COUNT; i++)
		{
			Barrier* pbarrier = nullptr;

			if(i == COUNT - 1)
			{
				pbarrier = &barrier;
			}

			a.submitNewTask<Task>(0.01, pbarrier, &counter);
		}

		barrier.wait();

		ANKI_TEST_EXPECT_EQ(counter.load(), COUNT);
	}

	// Many tasks that will _not_ finish
	{
		AsyncLoader a;
		a.init(alloc);

		for(U i = 0; i < 100; i++)
		{
			a.submitNewTask<Task>(0.0, nullptr, nullptr);
		}
	}

	// Tasks that allocate
	{
		AsyncLoader a;
		a.init(alloc);
		Barrier barrier(2);

		for(U i = 0; i < 10; i++)
		{
			Barrier* pbarrier = nullptr;

			if(i == 9)
			{
				pbarrier = &barrier;
			}

			a.submitNewTask<MemTask>(alloc, pbarrier);
		}

		barrier.wait();
	}

	// Tasks that allocate and never finished
	{
		AsyncLoader a;
		a.init(alloc);

		for(U i = 0; i < 10; i++)
		{
			a.submitNewTask<MemTask>(alloc, nullptr);
		}
	}

	// Pause/resume
	{
		AsyncLoader a;
		a.init(alloc);
		Atomic<U32> counter(0);
		Barrier barrier(2);

		// Check if the pause will sync
		a.submitNewTask<Task>(0.5, nullptr, &counter, 0);
		HighRezTimer::sleep(0.25); // Wait for the thread to pick the task...
		a.pause(); /// ...and then sync
		ANKI_TEST_EXPECT_EQ(counter.load(), 1);

		// Test resume
		a.submitNewTask<Task>(0.1, nullptr, &counter, 1);
		HighRezTimer::sleep(1.0);
		ANKI_TEST_EXPECT_EQ(counter.load(), 1);
		a.resume();

		// Sync
		a.submitNewTask<Task>(0.1, &barrier, &counter, 2);
		barrier.wait();

		ANKI_TEST_EXPECT_EQ(counter.load(), 3);
	}

	// Pause/resume
	{
		AsyncLoader a;
		a.init(alloc);
		Atomic<U32> counter(0);
		Barrier barrier(2);

		// Check task resubmit
		a.submitNewTask<Task>(0.0, &barrier, &counter, -1, false, true);
		barrier.wait();
		barrier.wait();
		ANKI_TEST_EXPECT_EQ(counter.load(), 2);

		// Check task pause
		a.submitNewTask<Task>(0.0, nullptr, &counter, -1, true, false);
		a.submitNewTask<Task>(0.0, nullptr, &counter, -1, false, false);
		HighRezTimer::sleep(1.0);
		ANKI_TEST_EXPECT_EQ(counter.load(), 3);
		a.resume();
		HighRezTimer::sleep(1.0);
		ANKI_TEST_EXPECT_EQ(counter.load(), 4);

		// Check both
		counter.set(0);
		a.submitNewTask<Task>(0.0, nullptr, &counter, 0, false, false);
		a.submitNewTask<Task>(0.0, nullptr, &counter, -1, true, true);
		a.submitNewTask<Task>(0.0, nullptr, &counter, 2, false, false);
		HighRezTimer::sleep(1.0);
		ANKI_TEST_EXPECT_EQ(counter.load(), 2);
		a.resume();
		HighRezTimer::sleep(1.0);
		ANKI_TEST_EXPECT_EQ(counter.load(), 4);
	}

	// Fuzzy test
	{
		AsyncLoader a;
		a.init(alloc);
		Barrier barrier(2);
		Atomic<U32> counter = {0};

		for(U i = 0; i < 10; i++)
		{
			Barrier* pbarrier = nullptr;

			if(i == 9)
			{
				pbarrier = &barrier;
			}

			a.submitNewTask<Task>(randRange(0.0, 0.5), pbarrier, &counter, i);
		}

		barrier.wait();
		ANKI_TEST_EXPECT_EQ(counter.load(), 10);
	}
}
Esempio n. 12
0
ANKI_TEST(Util, String)
{
	HeapAllocator<U8> alloc(allocAligned, nullptr);

	// Copy
	{
		String a, b;
		a.create(alloc, "123");
		b.create(alloc, a);

		ANKI_TEST_EXPECT_EQ(a, b);
		ANKI_TEST_EXPECT_EQ(b, "123");

		b.destroy(alloc);
		a.destroy(alloc);
		b.create(alloc, "321");
		a.create(alloc, b);
		ANKI_TEST_EXPECT_EQ(a, b);
		ANKI_TEST_EXPECT_EQ(a, "321");

		b.destroy(alloc);
		a.destroy(alloc);
	}

	// Move
	{
		String a;
		a.create(alloc, "123");
		String b(std::move(a));
		ANKI_TEST_EXPECT_EQ(a.isEmpty(), true);
		ANKI_TEST_EXPECT_EQ(b, "123");

		b.destroy(alloc);
		b.create(alloc, "321");
		a = std::move(b);
		ANKI_TEST_EXPECT_EQ(a, "321");
		ANKI_TEST_EXPECT_EQ(b.isEmpty(), true);
		a.destroy(alloc);
	}

	// Accessors
	{
		const char* s = "123";
		String a;
		a.create(alloc, s);
		ANKI_TEST_EXPECT_EQ(a[0], '1');
		ANKI_TEST_EXPECT_EQ(a[1], '2');
		ANKI_TEST_EXPECT_EQ(a[2], '3');

		U count = 0;
		for(char& c : a)
		{
			++c;
			++count;
		}

		ANKI_TEST_EXPECT_EQ(a, "234");
		ANKI_TEST_EXPECT_EQ(count, 3);

		ANKI_TEST_EXPECT_EQ(a.begin(), &a[0]);
		ANKI_TEST_EXPECT_EQ(a.end(), &a[0] + 3);
		a.destroy(alloc);
	}

	// Append
	{
		String a, b;

		b.create(alloc, "123");

		a.append(alloc, b);
		ANKI_TEST_EXPECT_EQ(a, "123");

		a.append(alloc, "456789");
		a.append(alloc, String());
		a.append(alloc, "");
		a.append(alloc, "0");
		ANKI_TEST_EXPECT_EQ(a, "1234567890");
		a.destroy(alloc);
		b.destroy(alloc);
	}

	// Compare
	{
#define COMPARE(x_, y_, op_)                                                                                           \
	a.append(alloc, x_);                                                                                               \
	b.append(alloc, y_);                                                                                               \
	ANKI_TEST_EXPECT_EQ(a op_ b, std::string(x_) op_ std::string(y_))                                                  \
	a.destroy(alloc);                                                                                                  \
	b.destroy(alloc);

		String a, b;
		COMPARE("123", "1233", <);
		COMPARE("0123", "1233", <=);
		COMPARE("ASDFA", "asdf90f", >);
		COMPARE(" %^*^^&", "aslkdfjb", >=);

#undef COMPARE
	}

	// sprintf
	{
		String a;

		// Simple
		a.sprintf(alloc, "12%c  %d", '3', 123);
		ANKI_TEST_EXPECT_EQ(a, "123  123");
		a.destroy(alloc);

		// Extreme
		const char* s = "1234567890ABCDEF!@#$%^&*()_+asfghjkl:,.;ljk\"><{}[]/";
		a.sprintf(alloc, "%s%s%s%s%s%s%s%s%s%s%s %d", s, s, s, s, s, s, s, s, s, s, s, 88);

		String b;
		for(U i = 0; i < 11; i++)
		{
			b.append(alloc, s);
		}
		b.append(alloc, " 88");

		ANKI_TEST_EXPECT_EQ(a, b);
		ANKI_TEST_EXPECT_EQ(a.getLength(), b.getLength());

		a.destroy(alloc);
		b.destroy(alloc);
	}

	// sprintf #2: Smaller result (will trigger another path)
	{
		String a;

		// Simple
		a.sprintf(alloc, "12%c  %d", '3', 123);
		ANKI_TEST_EXPECT_EQ(a, "123  123");
		a.destroy(alloc);

		// Extreme
		const char* s = "12345";
		a.sprintf(alloc, "%s%s %d", s, s, 88);

		String b;
		for(U i = 0; i < 2; i++)
		{
			b.append(alloc, s);
		}
		b.append(alloc, " 88");

		ANKI_TEST_EXPECT_EQ(a, b);
		ANKI_TEST_EXPECT_EQ(a.getLength(), b.getLength());

		a.destroy(alloc);
		b.destroy(alloc);
	}

	// Other create
	{
		String a;

		a.create(alloc, '1', 3);
		ANKI_TEST_EXPECT_EQ(a, "111");
		ANKI_TEST_EXPECT_EQ(a.getLength(), 3);

		a.destroy(alloc);
	}

	// toString
	{
		String a;
		a.toString(alloc, 123);
		ANKI_TEST_EXPECT_EQ(a, "123");
		a.destroy(alloc);

		a.toString(alloc, 123.123);
		ANKI_TEST_EXPECT_EQ(a, "123.123000");
		a.destroy(alloc);
	}

	// To number
	{
		I64 i;
		String a;
		a.create(alloc, "123456789");
		ANKI_TEST_EXPECT_NO_ERR(a.toI64(i));
		ANKI_TEST_EXPECT_EQ(i, 123456789);
		a.destroy(alloc);

		a.create(alloc, "-9223372036854775807");
		ANKI_TEST_EXPECT_NO_ERR(a.toI64(i));
		ANKI_TEST_EXPECT_EQ(i, -9223372036854775807);
		a.destroy(alloc);

		F64 f;
		a.create(alloc, "123456789.145");
		ANKI_TEST_EXPECT_NO_ERR(a.toF64(f));
		ANKI_TEST_EXPECT_EQ(f, 123456789.145);
		a.destroy(alloc);
	}
}
Esempio n. 13
0
ANKI_TEST(Util, StackAllocator)
{
	Foo::reset();

	// With simple string
	{
		StackAllocator<char> alloc(allocAligned, nullptr, 128);
		using Str = std::basic_string<char, std::char_traits<char>, StackAllocator<char>>;

		Str str(alloc);

		str = "lalala";
		str = "lalalalo";
	}

	// With vector
	{
		using All = StackAllocator<Foo>;
		All alloc(allocAligned, nullptr, (sizeof(Foo) + 1) * 10, alignof(Foo));
		std::vector<Foo, All> vec(alloc);

		vec.reserve(10);

		U sumi = 0;
		for(U i = 0; i < 10; i++)
		{
			std::cout << "pushing" << std::endl;
			vec.push_back(Foo(10 * i));
			sumi += 10 * i;
		}

		U sum = 0;

		for(const Foo& foo : vec)
		{
			sum += foo.x;
		}

		ANKI_TEST_EXPECT_EQ(sum, sumi);
	}

	// Copy around
	{
		typedef StackAllocator<Foo> Alloc;

		Alloc a(allocAligned, nullptr, (sizeof(Foo) + 1) * 10, alignof(Foo));

		Alloc b(allocAligned, nullptr, (sizeof(Foo) + 1) * 10, alignof(Foo));

		a = b;
		ANKI_TEST_EXPECT_EQ(a.getMemoryPool().getUsersCount(), 2);

		b = a;
		ANKI_TEST_EXPECT_EQ(&a.getMemoryPool(), &b.getMemoryPool());
		ANKI_TEST_EXPECT_EQ(a.getMemoryPool().getUsersCount(), 2);
	}

	ANKI_TEST_EXPECT_EQ(Foo::constructorCallCount, Foo::destructorCallCount);

	// End
	Foo::reset();
}
Esempio n. 14
0
ANKI_TEST(Util, List)
{
	HeapAllocator<U8> alloc(allocAligned, nullptr);

	// Simple
	{
		List<Foo> a;
		Error err = ErrorCode::NONE;

		a.emplaceBack(alloc, 10);
		a.emplaceBack(alloc, 11);

		U sum = 0;

		err = a.iterateForward([&](const Foo& f) -> Error
		{
			sum += f.x;
			return ErrorCode::NONE;
		});

		ANKI_TEST_EXPECT_EQ(err, ErrorCode::NONE);
		ANKI_TEST_EXPECT_EQ(sum, 21);

		a.destroy(alloc);
	}

	// Sort
	{
		List<I> a;
		Error err = ErrorCode::NONE;

		a.emplaceBack(alloc, 10);
		a.emplaceBack(alloc, 9);
		a.emplaceBack(alloc, 11);
		a.emplaceBack(alloc, 2);

		a.sort();

		Array<I, 4> arr = {{2, 9, 10, 11}};
		U u = 0;

		err = a.iterateForward([&](const I& i) -> Error
		{
			if(arr[u++] == i)
			{
				return ErrorCode::NONE;
			}
			else
			{
				return ErrorCode::UNKNOWN;
			}
		});

		ANKI_TEST_EXPECT_EQ(err, ErrorCode::NONE);

		a.sort([](I& a, I& b) -> Bool
		{
			return a > b;
		});

		Array<I, 4> arr2 = {{11, 10, 9, 2}};
		u = 0;

		err = a.iterateForward([&](const I& i) -> Error
		{
			if(arr2[u++] == i)
			{
				return ErrorCode::NONE;
			}
			else
			{
				return ErrorCode::UNKNOWN;
			}
		});

		ANKI_TEST_EXPECT_EQ(err, ErrorCode::NONE);

		a.destroy(alloc);
	}

	// Extreme sort
	{
		const U COUNT = 10000;
		List<Foo> a;
		std::list<Foo> b;

		for(U i = 0; i < COUNT; i++)
		{
			I randVal = rand();
			Foo f(randVal);

			a.pushBack(alloc, f);
			b.push_back(f);
		}

		//auto ta = HighRezTimer::getCurrentTime();
		b.sort([](const Foo& a, const Foo& b){return a.x < b.x;});
		//auto tb = HighRezTimer::getCurrentTime();
		a.sort([](const Foo& a, const Foo& b){return a.x < b.x;});
		//auto tc = HighRezTimer::getCurrentTime();

		//printf("%f %f\n", tb - ta, tc - tb);

		auto ait = a.getBegin();
		auto bit = b.begin();
		auto aend = a.getEnd();
		auto bend = b.end();

		while(ait != aend && bit != bend)
		{
			const Foo& afoo = *ait;
			const Foo& bfoo = *bit;

			ANKI_TEST_EXPECT_EQ(afoo, bfoo);
			++ait;
			++bit;
		}

		ANKI_TEST_EXPECT_EQ(ait, aend);
		ANKI_TEST_EXPECT_EQ(bit, bend);
		a.destroy(alloc);
	}

	// Iterate
	{
		List<I> a;
		Error err = ErrorCode::NONE;

		a.emplaceBack(alloc, 10);
		a.emplaceBack(alloc, 9);
		a.emplaceBack(alloc, 11);
		a.emplaceBack(alloc, 2);

		Array<I, 4> arr = {{10, 9, 11, 2}};
		U count = 0;
		
		// Forward
		List<I>::ConstIterator it = a.getBegin();
		for(; it != a.getEnd() && !err; ++it)
		{
			if(*it != arr[count++])
			{
				err = ErrorCode::UNKNOWN;
			}
		}
		
		ANKI_TEST_EXPECT_EQ(err, ErrorCode::NONE);

		// Backwards
		--it;
		for(; it != a.getBegin() && !err; --it)
		{
			if(*it != arr[--count])
			{
				err = ErrorCode::UNKNOWN;
			}
		}

		ANKI_TEST_EXPECT_EQ(err, ErrorCode::NONE);

		a.destroy(alloc);
	}

	// Erase
	{
		List<I> a;

		a.emplaceBack(alloc, 10);

		a.erase(alloc, a.getBegin());
		ANKI_TEST_EXPECT_EQ(a.isEmpty(), true);

		a.emplaceBack(alloc, 10);
		a.emplaceBack(alloc, 20);

		a.erase(alloc, a.getBegin() + 1);
		ANKI_TEST_EXPECT_EQ(10, *a.getBegin());

		a.emplaceFront(alloc, 5);
		a.emplaceBack(alloc, 30);

		ANKI_TEST_EXPECT_EQ(5, *(a.getBegin()));
		ANKI_TEST_EXPECT_EQ(10, *(a.getEnd() - 2));
		ANKI_TEST_EXPECT_EQ(30, *(a.getEnd() - 1));
		
		a.erase(alloc, a.getEnd() - 2);
		ANKI_TEST_EXPECT_EQ(5, *(a.getBegin()));
		ANKI_TEST_EXPECT_EQ(30, *(a.getEnd() - 1));

		a.erase(alloc, a.getBegin());
		a.erase(alloc, a.getBegin());
	}
}