mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
Added a sorted insert to vector, as well as cleaning up and extending the removal functions.
155 lines
3.4 KiB
C++
155 lines
3.4 KiB
C++
#include <chrono>
|
|
#include <iostream>
|
|
#include <limits>
|
|
#include <random>
|
|
#include <vector>
|
|
#include "kutil/linked_list.h"
|
|
#include "catch.hpp"
|
|
#include "container_helpers.h"
|
|
|
|
using namespace kutil;
|
|
|
|
const int test_list_size = 100;
|
|
|
|
template <typename T>
|
|
class ListVectorCompare :
|
|
public Catch::MatcherBase<std::vector<list_node<T>>>
|
|
{
|
|
public:
|
|
using item = list_node<T>;
|
|
using vector = std::vector<item>;
|
|
|
|
ListVectorCompare(const linked_list<T> &list, bool reversed) :
|
|
m_list(list), m_reverse(reversed) {}
|
|
|
|
virtual bool match (vector const& vec) const override
|
|
{
|
|
size_t index = m_reverse ? vec.size() - 1 : 0;
|
|
for (const T *i : m_list) {
|
|
if (i != &vec[index]) return false;
|
|
index += m_reverse ? -1 : 1;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
virtual std::string describe() const override
|
|
{
|
|
return "is the same as the given linked list";
|
|
}
|
|
|
|
private:
|
|
const linked_list<T> &m_list;
|
|
bool m_reverse;
|
|
};
|
|
|
|
template <typename T>
|
|
class IsSorted :
|
|
public Catch::MatcherBase<linked_list<T>>
|
|
{
|
|
public:
|
|
using item = list_node<T>;
|
|
using list = linked_list<T>;
|
|
|
|
IsSorted() {}
|
|
|
|
virtual bool match (list const& l) const override
|
|
{
|
|
int big = std::numeric_limits<int>::min();
|
|
for (const T *i : l) {
|
|
if (i->value < big) return false;
|
|
big = i->value;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
virtual std::string describe() const override
|
|
{
|
|
return "is sorted";
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
class ListContainsMatcher :
|
|
public Catch::MatcherBase<linked_list<T>>
|
|
{
|
|
public:
|
|
using item = list_node<T>;
|
|
using list = linked_list<T>;
|
|
|
|
ListContainsMatcher(const item &needle) : m_needle(needle) {}
|
|
|
|
virtual bool match (list const& l) const override
|
|
{
|
|
for (const T *i : l)
|
|
if (i == &m_needle) return true;
|
|
return false;
|
|
}
|
|
|
|
virtual std::string describe() const override
|
|
{
|
|
return "contains the given item";
|
|
}
|
|
|
|
const item &m_needle;
|
|
};
|
|
|
|
template <typename T>
|
|
ListVectorCompare<T> IsSameAsList(const linked_list<T> &list, bool reversed = false)
|
|
{
|
|
return ListVectorCompare<T>(list, reversed);
|
|
}
|
|
|
|
template <typename T>
|
|
ListContainsMatcher<T> ListContains(const list_node<T> &item)
|
|
{
|
|
return ListContainsMatcher<T>(item);
|
|
}
|
|
|
|
TEST_CASE( "Linked list tests", "[containers] [list]" )
|
|
{
|
|
linked_list<unsortableT> ulist;
|
|
|
|
int value = 0;
|
|
std::vector<list_node<unsortableT>> unsortables(test_list_size);
|
|
for (auto &i : unsortables) {
|
|
i.value = value++;
|
|
ulist.push_back(&i);
|
|
}
|
|
CHECK( ulist.length() == test_list_size );
|
|
CHECK_THAT( unsortables, IsSameAsList(ulist) );
|
|
|
|
linked_list<unsortableT> ulist_reversed;
|
|
|
|
for (auto &i : unsortables) {
|
|
ulist.remove(&i);
|
|
ulist_reversed.push_front(&i);
|
|
}
|
|
|
|
CHECK( ulist_reversed.length() == test_list_size );
|
|
CHECK_THAT( unsortables, IsSameAsList(ulist_reversed, true) );
|
|
|
|
auto &removed = unsortables[test_list_size / 2];
|
|
ulist_reversed.remove(&removed);
|
|
CHECK( ulist_reversed.length() == test_list_size - 1 );
|
|
CHECK_THAT( ulist_reversed, !ListContains(removed) );
|
|
}
|
|
|
|
TEST_CASE( "Sorted list tests", "[containers] [list]" )
|
|
{
|
|
using clock = std::chrono::system_clock;
|
|
unsigned seed = clock::now().time_since_epoch().count();
|
|
std::default_random_engine rng(seed);
|
|
std::uniform_int_distribution<int> gen(1, 1000);
|
|
|
|
linked_list<sortableT> slist;
|
|
CHECK( slist.length() == 0 );
|
|
|
|
std::vector<list_node<sortableT>> sortables(test_list_size);
|
|
for (auto &i : sortables) {
|
|
i.value = gen(rng);
|
|
slist.sorted_insert(&i);
|
|
}
|
|
CHECK( slist.length() == test_list_size );
|
|
CHECK_THAT( slist, IsSorted<sortableT>() );
|
|
}
|