1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-02-24 05:37:14 +01:00
SqMod/vendor/POCO/Foundation/testsuite/src/OrderedContainersTest.h
Sandu Liviu Catalin 4a6bfc086c Major plugin refactor and cleanup.
Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
2021-01-30 08:51:39 +02:00

337 lines
9.8 KiB
C++

//
// OrderedContainersTest.h
//
// Definition of the OrderedContainersTest class.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef OrderedContainersTest_INCLUDED
#define OrderedContainersTest_INCLUDED
#include "Poco/Foundation.h"
#include "CppUnit/TestCase.h"
#include "Poco/OrderedMap.h"
#include "Poco/OrderedSet.h"
#include "ordered_map_util.h"
#include <tuple>
#include <deque>
#ifdef POCO_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable : 4244)
#pragma warning(disable : 4267)
#endif // POCO_COMPILER_MSVC
class OrderedContainersTest: public CppUnit::TestCase
{
public:
OrderedContainersTest(const std::string& name);
~OrderedContainersTest();
void testMapInsert();
void testRangeInsert();
void testInsertWithHint();
void testEmplace();
void testTryEmplace();
void testTryEmplace2();
void testTryEmplaceHint();
void testInsertOrAssign();
void testInsertOrAssignHint();
void testInsertAtPosition();
void testTryEmplaceAtPosition();
void testRangeErase();
void testMapEraseLoop();
void testMapInsertEraseInsert();
void testRangeEraseAll();
void testRangeEraseSameIterators();
void testUnorderedErase();
void testCompare();
void testClear();
void testReverseIterator();
void testIteratorArithmetic();
void testIteratorComparators();
void testModifyValue();
void testAssignOperator();
void testMoveConstructor();
void testMoveOperator();
void testReassignMovedObjectMoveConstructor();
void testReassignMovedObjectMoveOperator();
void testCopyConstructorOperator();
void testAt();
void testEqualRange();
void testData();
void testAccessOperator();
void testSwap();
void testFrontBack();
void testNth();
void testHeterogeneousLookups();
void testEmptyMap();
void testPrecalculatedHash();
void testSetInsert();
void testCustomAllocator1();
void setUp();
void tearDown();
static CppUnit::Test* suite();
private:
#define testMapFuncFwd(cont, func) { \
func<cont<std::int64_t, std::int64_t>>(); \
func<cont<std::int64_t, std::int64_t, \
std::hash<std::int64_t>, std::equal_to<std::int64_t>, \
std::allocator<std::pair<std::int64_t, std::int64_t>>, \
std::deque<std::pair<std::int64_t, std::int64_t>>>>(); \
func<cont<std::int64_t, std::int64_t, \
std::hash<std::int64_t>, std::equal_to<std::int64_t>, \
std::allocator<std::pair<std::int64_t, std::int64_t>>, \
std::vector<std::pair<std::int64_t, std::int64_t>>>>(); \
func<cont<std::string, std::string>>(); \
func<cont<std::string, std::string, mod_hash<9>>>(); \
}
// needs significant CppUnit or test changes, maybe one day ...
//func<cont<move_only_test, move_only_test, mod_hash<9>>>();
#define testSetFuncFwd(cont, func) { \
func<cont<std::int64_t, std::hash<std::int64_t>, \
std::equal_to<std::int64_t>, \
std::allocator<std::int64_t>, \
std::deque<std::int64_t>>>(); \
func<cont<std::int64_t, std::hash<std::int64_t>, \
std::equal_to<std::int64_t>, \
std::allocator<std::int64_t>, \
std::vector<std::int64_t>>>(); \
func<cont<std::int64_t, mod_hash<9>>>(); \
func<cont<std::string>>(); \
func<cont<std::string, mod_hash<9>>>(); \
}
template <typename T>
void testMapInsertImpl()
{
// insert x values, insert them again, check values through find, check order through iterator
using key_tt = typename T::key_type;
using value_tt = typename T::mapped_type;
const std::size_t nb_values = 1000;
T map;
typename T::iterator it;
bool inserted;
for(std::size_t i = 0; i < nb_values; i++)
{
// Avoid sequential values by splitting the values with modulo
const std::size_t insert_val = (i%2 == 0) ? i : nb_values + i;
std::tie(it, inserted) = map.insert({utils::get_key<key_tt>(insert_val),
utils::get_value<value_tt>(insert_val)});
assertEquals(it->first, utils::get_key<key_tt>(insert_val));
assertEquals(it->second, utils::get_value<value_tt>(insert_val));
assertTrue(inserted);
}
assertEquals(map.size(), nb_values);
for(std::size_t i = 0; i < nb_values; i++)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
std::tie(it, inserted) = map.insert({utils::get_key<key_tt>(insert_val),
utils::get_value<value_tt>(insert_val + 1)});
assertEquals(it->first, utils::get_key<key_tt>(insert_val));
assertEquals(it->second, utils::get_value<value_tt>(insert_val));
assertTrue(!inserted);
}
assertEquals(map.size(), nb_values);
for(std::size_t i = 0; i < nb_values; i++)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
it = map.find(utils::get_key<key_tt>(insert_val));
assertEquals(it->first, utils::get_key<key_tt>(insert_val));
assertEquals(it->second, utils::get_value<value_tt>(insert_val));
}
std::size_t i = 0;
for(const auto& key_value: map)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
assertEquals(key_value.first, utils::get_key<key_tt>(insert_val));
assertEquals(key_value.second, utils::get_value<value_tt>(insert_val));
i++;
}
}
template <typename T>
void testMapEraseLoopImpl()
{
// insert x values, delete all one by one
std::size_t nb_values = 1000;
T map = utils::get_filled_hash_map<T>(nb_values);
T map2 = utils::get_filled_hash_map<T>(nb_values);
auto it = map.begin();
// Use second map to check for key after delete as we may not copy the key with move-only types.
auto it2 = map2.begin();
while(it != map.end()) {
it = map.erase(it);
--nb_values;
assertEquals(map.count(it2->first), 0);
assertEquals(map.size(), nb_values);
++it2;
}
assertTrue(map.empty());
}
template <typename T>
void testMapInsertEraseInsertImpl()
{
// insert x/2 values, delete x/4 values, insert x/2 values, find each value, check order of values
using key_tt = typename T::key_type; using value_tt = typename T:: mapped_type;
const std::size_t nb_values = 2000;
T map;
typename T::iterator it;
bool inserted;
// Insert nb_values/2
for(std::size_t i = 0; i < nb_values/2; i++)
{
std::tie(it, inserted) = map.insert({utils::get_key<key_tt>(i), utils::get_value<value_tt>(i)});
assertEquals(it->first, utils::get_key<key_tt>(i));
assertEquals(it->second, utils::get_value<value_tt>(i));
assertTrue(inserted);
}
assertEquals(map.size(), nb_values/2);
// Delete nb_values/4
for(std::size_t i = 0; i < nb_values/2; i++)
{
if(i%2 == 0) {
assertEquals(map.erase(utils::get_key<key_tt>(i)), 1);
}
}
assertEquals(map.size(), nb_values/4);
// Insert nb_values/2
for(std::size_t i = nb_values/2; i < nb_values; i++)
{
std::tie(it, inserted) = map.insert({utils::get_key<key_tt>(i), utils::get_value<value_tt>(i)});
assertEquals(it->first, utils::get_key<key_tt>(i));
assertEquals(it->second, utils::get_value<value_tt>(i));
assertTrue(inserted);
}
assertEquals(map.size(), nb_values-nb_values/4);
// Find
for(std::size_t i = 0; i < nb_values; i++)
{
if(i%2 == 0 && i < nb_values/2)
{
it = map.find(utils::get_key<key_tt>(i));
assertTrue(it == map.cend());
}
else {
it = map.find(utils::get_key<key_tt>(i));
assertEquals(it->first, utils::get_key<key_tt>(i));
assertEquals(it->second, utils::get_value<value_tt>(i));
}
}
// Check order
std::size_t i = 1;
for(const auto& key_value: map)
{
if(i < nb_values/2)
{
assertEquals(key_value.first, utils::get_key<key_tt>(i));
assertEquals(key_value.second, utils::get_value<value_tt>(i));
i = std::min(i+2, nb_values/2);
}
else
{
assertEquals(key_value.first, utils::get_key<key_tt>(i));
assertEquals(key_value.second, utils::get_value<value_tt>(i));
i++;
}
}
}
template <typename T>
void testSetInsertImpl()
{
// insert x values, insert them again, check values through find, check order through iterator
using key_t = typename T::key_type;
const std::size_t nb_values = 1000;
T set;
typename T::iterator it;
bool inserted;
for(std::size_t i = 0; i < nb_values; i++)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
std::tie(it, inserted) = set.insert(utils::get_key<key_t>(insert_val));
assertEquals(*it, utils::get_key<key_t>(insert_val));
assertTrue(inserted);
}
assertEquals(set.size(), nb_values);
for(std::size_t i = 0; i < nb_values; i++)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
std::tie(it, inserted) = set.insert(utils::get_key<key_t>(insert_val));
assertEquals(*it, utils::get_key<key_t>(insert_val));
assertTrue(!inserted);
}
assertEquals(set.size(), nb_values);
for(std::size_t i = 0; i < nb_values; i++)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
it = set.find(utils::get_key<key_t>(insert_val));
assertEquals(*it, utils::get_key<key_t>(insert_val));
}
std::size_t i = 0;
for(const auto& value: set)
{
const std::size_t insert_val = (i%2 == 0)?i:nb_values + i;
assertEquals(value, utils::get_key<key_t>(insert_val));
i++;
}
}
};
#ifdef POCO_COMPILER_MSVC
#pragma warning(pop)
#endif // POCO_COMPILER_MSVC
#endif // OrderedContainersTest_INCLUDED