Browse Source

"fixed" the sort, will require more work

master
Ludovic 'Archivist' Lagouardette 2 years ago
parent
commit
3b06e09f09
12 changed files with 306 additions and 38 deletions
  1. +1
    -1
      .vscode/launch.json
  2. +1
    -1
      Makefile
  3. +44
    -0
      include/gp/algorithms/partition.hpp
  4. +62
    -12
      include/gp/algorithms/sort.hpp
  5. +36
    -2
      include/gp/containers/dynarray.hpp
  6. +11
    -11
      include/gp/containers/vector.hpp
  7. +5
    -5
      include/gp/functional/function.hpp
  8. +43
    -3
      include/gp/utils/iterators/pointer_iterator.hpp
  9. +37
    -0
      tests/arena_test.cpp
  10. +63
    -0
      tests/dynarray_test.cpp
  11. +2
    -2
      tests/flat_tree_test.cpp
  12. +1
    -1
      tests/math.cpp

+ 1
- 1
.vscode/launch.json View File

@ -8,7 +8,7 @@
"type": "gdb",
"request": "launch",
"name": "Launch Program",
"target": "./bin/tests",
"target": "${workspaceRoot}/bin/tests",
"cwd": "${workspaceRoot}",
"valuesFormatting": "parseText",
"env": {"LLVM_PROFILE_FILE":"./bin/tests.profraw"}

+ 1
- 1
Makefile View File

@ -10,7 +10,7 @@ EVERY_TEST_FILE= $(shell find tests/ -name "*.cpp" -type "f")
TEST_OBJECTS := $(EVERY_TEST_FILE:%.cpp=bin/obj/%.test.o)
all: tests
bin/obj/%.test.o: %.cpp
bin/obj/%.test.o: %.cpp $(EVERY_USEFUL_FILE)
@mkdir -p $(@D)
$(CXX) $(CXXFLAGS) -DUSE_CATCH -Itests -Iinclude -o $@ -c $<

+ 44
- 0
include/gp/algorithms/partition.hpp View File

@ -0,0 +1,44 @@
#pragma once
#include <gp/algorithms/move.hpp>
namespace gp {
template<typename it_t, typename pred>
it_t lomuto_partition(it_t first, it_t last, pred predicate = pred{}) {
auto pivot = *--it_t(last);
auto i = --it_t(first);
for(auto j = first; j != last; ++j) {
if(!predicate(*j, pivot)){
++i;
gp::swap(*i, *j);
}
}
return i;
}
template<typename it_t, typename pred>
it_t hoare_partition(it_t first, it_t last, pred predicate = pred{}) {
while(first != last) {
while(predicate(*first)) {
++first;
if(first == last) return first;
}
do {
--last;
if(first == last) return first;
} while(!predicate(*last));
swap(*first, *last);
++first;
}
return first;
}
template<typename it_t, typename pred>
it_t partition(it_t first, it_t last, pred predicate = pred{}) {
return gp::hoare_partition(first, last, predicate);
}
}

+ 62
- 12
include/gp/algorithms/sort.hpp View File

@ -1,25 +1,75 @@
#pragma once
#include <gp/algorithms/move.hpp>
#include <gp/algorithms/partition.hpp>
#include <iostream>
namespace gp {
template<typename it_t, typename pred>
void selection_sort(it_t first, it_t last, pred predicate = pred{}) {
while(first != last) {
auto traveler = first;
auto it = first;
it++;
for(;it!=last;it++) {
if(predicate(*it, *traveler)) traveler = it;
namespace __details {
template<typename it_t, typename pred>
void selection_sort(it_t first, it_t last, pred predicate = pred{}) {
while(first != last) {
it_t traveler = first;
it_t it = first;
it++;
for(;it!=last;it++) {
if(predicate(*it, *traveler)) traveler = it;
}
gp::swap(*first, *traveler);
first++;
}
}
template<typename it_t, typename pred>
bool sort2(auto it0, auto it1, pred predicate = pred{}){
if(it0 != it1 && predicate(*it1, *it0)) {
gp::swap(*it0, *it1);
return true;
}
return false;
};
template<typename it_t, typename pred>
void quick_sort(it_t first, it_t last, pred predicate = pred{}) {
using __details::sort2;
if(last - first <= 2) {
auto nit = first + (size_t)(last == first + 1);
__details::sort2<it_t>(first, nit, predicate);
return;
}
auto pivot_v = *(first + (last - first)/2);
auto pivot = gp::partition(first, last, [&](auto& a) -> bool{
return predicate(a, pivot_v);
});
gp::__details::quick_sort(first, pivot, predicate);
gp::__details::quick_sort(pivot, last, predicate);
}
template<typename it_t, typename pred>
void bubble_sort(it_t first, it_t last, pred predicate = pred{}) {
if(last - first <= 2) {
auto nit = first + (size_t)(last == first + 1);
__details::sort2<it_t>(first, nit, predicate);
return;
}
gp::swap(*first, *traveler);
first++;
size_t swaps;
do {
swaps = 0;
auto it = first;
auto nit = it + 1;
for(;;) {
swaps += __details::sort2<it_t>(it, nit, predicate);
++it; ++nit;
if(nit == last) break;
}
} while(swaps);
}
}
template<typename it_t, typename pred>
void sort(it_t first, it_t last, pred predicate = pred{}) {
return selection_sort(first, last, predicate);
return ">gp::__details::bubble_sort(first, last, predicate);
}
}

+ 36
- 2
include/gp/containers/dynarray.hpp View File

@ -70,12 +70,36 @@ namespace gp {
}
}
cm">/*dynarray(dynarray&& oth)
n">dynarray(dynarray&& oth)
{
for(auto& ref : oth) {
emplace_back(gp::move(ref));
}
oth.sz = 0;
}
dynarray& operator=(const dynarray& oth) {
for(auto& self : data) {
self.clear();
}
sz = 0;
for(auto& ref : oth) {
push_back(ref);
}
return *this;
}
dynarray& operator=(dynarray&& oth) {
for(auto& self : data) {
self.clear();
}
sz = 0;
for(auto& ref : oth) {
emplace_back(gp::forward<T>(ref));
}
}*/
oth.sz = 0;
return *this;
}
constexpr associated_iterator begin()
{
@ -87,6 +111,16 @@ namespace gp {
return associated_iterator((T*)&data[sz]);
}
constexpr const associated_iterator begin() const
{
return associated_iterator((T*)&data[0]);
}
constexpr const associated_iterator end() const
{
return associated_iterator((T*)&data[sz]);
}
constexpr associated_const_iterator cbegin() const
{
return associated_const_iterator((T*)&data[0]);

+ 11
- 11
include/gp/containers/vector.hpp View File

@ -293,50 +293,50 @@ namespace gp{
return gp::move(ret_val);
}
void remove(pointer_iterator<T, 1> it) {
for(auto step = it + 1; step<end(); step++) {
void remove(gp::pointer_iterator<T, 1> it) {
for(auto step = it + 1; step!=end(); step++) {
(*it++) = gp::move(*step);
}
*rbegin().~T();
p">(*rbegin()).~T();
sz -= 1;
}
constexpr pointer_iterator<T, 1> begin()
constexpr gp::pointer_iterator<T, 1> begin()
{
return associated_iterator(&ary[0]);
}
constexpr pointer_iterator<T, 1> end()
constexpr gp::pointer_iterator<T, 1> end()
{
return associated_iterator(&ary[sz]);
}
constexpr const_pointer_iterator<T, 1> cbegin() const
constexpr gp::const_pointer_iterator<T, 1> cbegin() const
{
return associated_const_iterator(&ary[0]);
}
constexpr const_pointer_iterator<T, 1> cend() const
constexpr gp::const_pointer_iterator<T, 1> cend() const
{
return associated_const_iterator(&ary[sz]);
}
constexpr pointer_iterator<T, -1> rbegin()
constexpr gp::pointer_iterator<T, -1> rbegin()
{
return associated_riterator(&ary[sz-1]);
}
constexpr pointer_iterator<T, -1> rend()
constexpr gp::pointer_iterator<T, -1> rend()
{
return associated_riterator(ary-1);
}
constexpr const_pointer_iterator<T, -1> crbegin() const
constexpr gp::const_pointer_iterator<T, -1> crbegin() const
{
return associated_const_riterator(&ary[sz-1]);
}
constexpr const_pointer_iterator<T, -1> crend() const
constexpr gp::const_pointer_iterator<T, -1> crend() const
{
return associated_const_riterator(ary-1);
}

+ 5
- 5
include/gp/functional/function.hpp View File

@ -157,11 +157,11 @@ namespace gp{
}
function& operator=(function&& rhs) {
gp::swap(alloc, rhs.alloc);
gp::swap(invokator, rhs.invokator);
gp::swap(condestructor, rhs.condestructor);
gp::swap(data_ptr,rhs.data_ptr);
gp::swap(data_size,rhs.data_size);
swap(alloc, rhs.alloc);
swap(invokator, rhs.invokator);
swap(condestructor, rhs.condestructor);
swap(data_ptr,rhs.data_ptr);
swap(data_size,rhs.data_size);
return *this;
}

+ 43
- 3
include/gp/utils/iterators/pointer_iterator.hpp View File

@ -19,7 +19,7 @@ namespace gp {
{
T* data; /**< the only data field of the class */
typedef T value_type; /**< The type of which a reference will be returned on dereferencing */
typedef std::size_t difference_type; /**< The type of the substraction of two pointers */
typedef std::intptr_t difference_type; /**< The type of the substraction of two pointers */
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see iterator_type_t */
/**
@ -81,6 +81,11 @@ namespace gp {
return pointer_iterator{data+sign*offset};
}
constexpr pointer_iterator operator+(const difference_type offset) const
{
return pointer_iterator{data+sign*offset};
}
constexpr pointer_iterator operator+(const int offset) const
{
return pointer_iterator{data+sign*offset};
@ -91,6 +96,11 @@ namespace gp {
return pointer_iterator{data-sign*offset};
}
constexpr pointer_iterator operator-(const difference_type offset) const
{
return pointer_iterator{data-sign*offset};
}
constexpr pointer_iterator operator-(const int offset) const
{
return pointer_iterator{data-sign*offset};
@ -98,7 +108,7 @@ namespace gp {
constexpr difference_type operator-(const pointer_iterator& oth) const
{
return (p">(T*)data-(T*)oth.data)*sign;
return (data-oth.data)*sign;
}
constexpr bool operator==(const pointer_iterator oth) const
@ -116,10 +126,20 @@ namespace gp {
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
}
constexpr bool after_or_equal(const pointer_iterator oth) const
{
return reinterpret_cast<std::intptr_t>(data) >= reinterpret_cast<std::intptr_t>(oth.data);
}
constexpr bool operator<=(const pointer_iterator oth) const
{
return before_or_equal(oth);
}
constexpr bool operator>=(const pointer_iterator oth) const
{
return after_or_equal(oth);
}
};
/**
@ -134,7 +154,7 @@ namespace gp {
{
const T* data; /**< @see pointer_iterator */
typedef T value_type; /**< @see pointer_iterator */
typedef std::size_t difference_type; /**< @see pointer_iterator */
typedef std::intptr_t difference_type; /**< @see pointer_iterator */
static constexpr iterator_type_t iterator_type = iterator_type_t::contiguous_iterator; /**< @see pointer_iterator */
constexpr const_pointer_iterator(const const_pointer_iterator& oth)
@ -187,11 +207,21 @@ namespace gp {
return const_pointer_iterator{data+sign*offset};
}
constexpr const_pointer_iterator operator+(const difference_type offset) const
{
return const_pointer_iterator{data+sign*offset};
}
constexpr const_pointer_iterator operator+(const int offset) const
{
return const_pointer_iterator{data+sign*offset};
}
constexpr const_pointer_iterator operator-(const difference_type offset) const
{
return const_pointer_iterator{data-sign*offset};
}
constexpr const_pointer_iterator operator-(const std::size_t offset) const
{
return const_pointer_iterator{data-sign*offset};
@ -222,9 +252,19 @@ namespace gp {
return reinterpret_cast<std::intptr_t>(data) <= reinterpret_cast<std::intptr_t>(oth.data);
}
constexpr bool after_or_equal(const const_pointer_iterator oth) const
{
return reinterpret_cast<std::intptr_t>(data) >= reinterpret_cast<std::intptr_t>(oth.data);
}
constexpr bool operator<=(const const_pointer_iterator oth) const
{
return before_or_equal(oth);
}
constexpr bool operator>=(const const_pointer_iterator oth) const
{
return after_or_equal(oth);
}
};
}

+ 37
- 0
tests/arena_test.cpp View File

@ -0,0 +1,37 @@
#include "gp/utils/pointers.hpp"
#include "gp/utils/allocators/arena.hpp"
#include "test_scaffold.h"
#include "allocator.hpp"
#include <memory>
struct arena_test : public test_scaffold {
uint32_t seed;
arena_test() {
name = __FILE__ ":1";
}
virtual int run() {
int return_val = 0;
std::unique_ptr<gp::array<char, 4096*4>> store = std::make_unique<gp::array<char, 4096*4>>();
gp::arena alloc{&*store->begin(), store->size()};
auto v = gp::unique_ptr<uint64_t>::make(alloc, 1024);
gp::arena alloc2{alloc, 1024};
gp::arena alloc3{};
{
auto v2 = gp::unique_ptr<uint64_t>::make(alloc2, 1024);
void* some_memory = alloc2.allocate(128);
if(!some_memory) return_val++;
if(alloc2.deallocate(nullptr)) return_val++;
}
{
if(alloc3.allocate(4)) return_val++;
if(alloc3.deallocate(nullptr)) return_val++;
}
alloc2.reset();
return return_val;
}
};
append_test dummy_8djbvs543(new arena_test{});

+ 63
- 0
tests/dynarray_test.cpp View File

@ -0,0 +1,63 @@
#include "gp/containers/dynarray.hpp"
#include "gp/containers/vector.hpp"
#include "gp/algorithms/sort.hpp"
#include "test_scaffold.h"
#include "allocator.hpp"
#include <memory>
#include <random>
#include <iostream>
#include <string>
#include <algorithm>
typedef std::mt19937_64 cheap_rand;
struct dynarray_test : public test_scaffold {
uint32_t seed;
dynarray_test() {
name = __FILE__ ":1_seed";
seed = std::random_device{}();
name += std::to_string(seed);
}
virtual int run() {
using val = gp::dynarray<int, 100>;
cheap_rand setter(seed);
std::unique_ptr<gp::array<char, 4096*4096>> store = std::make_unique<gp::array<char, 4096*4096>>();
gp::buddy alloc{&*store->begin(), store->size()};
gp::vector<val> vals{alloc};
std::uniform_int_distribution<int> dist(0,99);
for(int i = 0; i < 1000; i++) {
val insert{};
int max = dist(setter);
for(int b = 0; b < max; b++) {
insert.emplace_back(b);
}
vals.emplace_back(insert);
}
for(int i = 0; i < vals.size(); i++) {
for(int j = i+1; j < vals.size(); j++) {
if(!(vals[i] != vals[j])) {
if(vals[i] == vals[j]) {
vals.remove(vals.begin()+j);
j--;
}
}
}
}
gp::sort(vals.begin(), vals.end(), [](const val& a, const val& b){
return a.size() < b.size();
});
return vals.size() > 100;
}
};
append_test dummy_afdglys543(new dynarray_test{});

+ 2
- 2
tests/flat_tree_test.cpp View File

@ -12,9 +12,9 @@ struct flat_tree_test : public test_scaffold {
gp::flat_tree<int, 7> hello(v);
for(auto elem : hello) {
n">std::cout << elem << std::endl;
c1">//std::cout << elem << std::endl;
}
// TODO: implement a proper test, not this sad placeholder
return 0;
}
};

+ 1
- 1
tests/math.cpp View File

@ -193,7 +193,7 @@ struct math_funcs_test : public test_scaffold {
this->low = low;
this->high = high;
seed = std::random_device{}();
name = __FILE__ ":4_sort_pair";
name = __FILE__ ":4_math_funcs";
name += std::to_string(seed);
}

Loading…
Cancel
Save