Iterator sample

Run Settings
LanguageC++
Language Version
Run Command
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <assert.h> #include <initializer_list> #include "index_iter.h" #include "list.h" #include "linked_list.h" int main() { auto l = List<int>{ 7, 3, 2 }; #if 0 printf("C Style\n"); for (size_t i = 0; i < l.count; ++i) { auto value = l[i]; printf("%zu: %i\n", i, value); } #endif #if 0 printf("Iterator in C style loop\n"); auto iter = l.index(); auto begin = iter.begin(); auto end = iter.end(); for (auto it = begin; it != end; ++it) { auto [value, i] = *it; printf("%zu: %i\n", i, value); } #endif #if 0 printf("C++ Iterator\n"); for (auto [value, i] : l.index()) { printf("%zu: %i\n", i, value); } #endif #if 0 printf("C++ Iterator without index\n"); for (auto value : l) { printf("%i\n", value); } #endif #if 1 auto list = Linked_List<int> {934, 482, 349, 832}; list.reserve(5); list.add(91); list.add(82); list.add_range({123, 421, 999}); #else auto list = Linked_List<int> {}; list.add(73); list.add(52); list.add(98); list.add(23); list.add(91); list.add(82); #endif #if 1 printf("Linked list\n"); for (auto value : list) { printf("%i\n", value); } #endif #if 0 printf("Linked list with index\n"); for (auto [value, i] : list.index()) { printf("%zu: %i\n", i, value); } #endif #if 0 printf("Linked list ptr\n"); printf("%p\n", &list.first->elements[0]); printf("%p\n", &list.first->next->elements[0]); for (auto ptr : list.iter_ptr()) { printf("%i, %p\n", *ptr, ptr); } #endif #if 1 printf("Linked list ptr with index\n"); printf("%p\n", &list.first->elements[0]); printf("%p\n", &list.first->next->elements[0]); for (auto [ptr, index] : list.iter_ptr().index()) { printf("%zu: %i, %p\n", index, *ptr, ptr); } #endif #if 1 printf("Linked list indexing\n"); printf("%i\n", list[0]); printf("%i\n", list[1]); printf("%i\n", list[2]); printf("%i\n", list[3]); printf("%i\n", list[4]); printf("%i\n", list[5]); #endif list.release(); return 0; }
template<typename Value> struct Index_Iter_Value { Value value; size_t index; }; template<typename Value, typename Iter, typename End> struct Index_Iter { Iter iter; End iter_end; size_t index; Index_Iter begin() { return *this; } End end() { return iter_end; } Index_Iter operator++() { index += 1; ++iter; return *this; } bool operator!=(End other) { return this->iter != other; }; Index_Iter_Value<Value> operator*() { return Index_Iter_Value<Value> { .value = *iter, .index = index }; }; }; template<typename T, typename Iter, typename End> Index_Iter<T, Iter, End> index_iter(Iter iter, End iter_end) { return Index_Iter<T, Iter, End> { .iter = iter, .iter_end = iter_end, }; }
template<typename T> struct List_Iter { size_t count; T *elem; size_t index; List_Iter<T> operator++() { index += 1; return *this; } bool operator!=(size_t end_index) { return this->index != end_index; }; T operator*() { return elem[index]; }; }; template<typename T> struct List { size_t count; size_t capacity; T *elem; List(std::initializer_list<T> list) { count = list.size(); capacity = count; elem = 0; if (count == 0) return; elem = (T *)calloc(capacity * sizeof(T), 1); size_t i = 0; for (T e : list) { elem[i] = e; i += 1; } } void add(T v) { if (elem == 0) { capacity = 4; elem = (T *)calloc(capacity * sizeof(T), 1); } else if (count >= capacity) { size_t new_capacity = capacity * 2; T *new_elem = (T *)calloc(new_capacity * sizeof(T), 1); memmove(new_elem, elem, count * sizeof(T)); free(elem); elem = new_elem; capacity = new_capacity; } elem[count] = v; count += 1; } T& operator [](intptr_t i) { assert(i >= 0 && "index is negative"); assert(i < count && "index is out of range"); return elem[i]; } void release() { free(elem); elem = 0; count = 0; capacity = 0; } List_Iter<T> begin() { return List_Iter<T> { .count = count, .elem = elem, .index = 0, }; } size_t end() { return count; } Index_Iter<T, List_Iter<T>, size_t> index() { return index_iter<T>(begin(), end()); } };
template<typename T> struct Linked_List_Link { Linked_List_Link<T> *next; uint32_t count; uint32_t capacity; T elements[0]; }; template<typename T> struct Linked_List_Iter { Linked_List_Link<T> *link; uint32_t index; Linked_List_Iter<T> operator++() { index += 1; if (index >= link->count) { index = 0; link = link->next; } return *this; } bool operator!=(bool stub) { return link; }; T operator*() { return link->elements[index]; }; }; template<typename T> struct Linked_List_Iter_Ptr { Linked_List_Link<T> *link; uint32_t index; Linked_List_Iter_Ptr<T> operator++() { index += 1; if (index >= link->count) { index = 0; link = link->next; } return *this; } bool operator!=(bool stub) { return link; }; T *operator*() { return &link->elements[index]; }; }; template<typename T> struct Linked_List_Iter_Ptr_Container { Linked_List_Link<T> *first; Linked_List_Iter_Ptr<T> begin() { return Linked_List_Iter_Ptr<T> { .link = first, .index = 0, }; } bool end() { return false; } Index_Iter<T *, Linked_List_Iter_Ptr<T>, bool> index() { return index_iter<T *>(begin(), end()); } }; template<typename T> struct Linked_List { size_t count; Linked_List_Link<T> *first; Linked_List_Link<T> *last; Linked_List(std::initializer_list<T> list) { count = 0; first = 0; last = 0; if (list.size() == 0) { return; } reserve(list.size() > 4 ? list.size() : 4); // add_range_reserved ? add_range(list); } void add(T v) { add_range({v}); } void add_range(std::initializer_list<T> list) { size_t reserve_count = list.size(); if (reserve_count == 0) { return; } reserve(reserve_count); auto link = last; for (T e : list) { if (last->count >= last->capacity) { last = last->next; } last->elements[last->count] = e; last->count += 1; count += 1; } } void reserve(size_t reserve_count) { if (reserve_count == 0) { return; } auto link = last; if (link == 0) { auto allocation_size = (size_t)&((Linked_List_Link<T> *)0)->elements + sizeof(T) * reserve_count; first = (Linked_List_Link<T> *)calloc(allocation_size, 1); first->capacity = reserve_count; last = first; link = first; } else { intptr_t reserve_counter = reserve_count; while (link->next != 0) { reserve_counter -= link->capacity - link->count; link = link->next; } reserve_counter -= link->capacity - link->count; if (reserve_counter > 0) { auto new_link_capacity = count > (size_t)reserve_counter ? count : (size_t)reserve_counter; auto allocation_size = (size_t)&((Linked_List_Link<T> *)0)->elements + sizeof(T) * new_link_capacity; link->next = (Linked_List_Link<T> *)calloc(allocation_size, 1); link->next->capacity = new_link_capacity; link = link->next; } } } T& operator [](intptr_t i) { assert(i >= 0 && "index is negative"); assert(i < count && "index is out of range"); auto link = first; while (i >= (intptr_t)link->count) { i -= link->count; assert(link->next != 0 && "index is out of range"); link = link->next; } return link->elements[i]; } void release() { auto link = first; while (link != 0) { auto next = link->next; free(link); link = next; } first = 0; count = 0; } Linked_List_Iter<T> begin() { return Linked_List_Iter<T> { .link = first, .index = 0, }; } bool end() { return false; } Index_Iter<T, Linked_List_Iter<T>, bool> index() { return index_iter<T>(begin(), end()); } Linked_List_Iter_Ptr_Container<T> iter_ptr() { return Linked_List_Iter_Ptr_Container<T> { .first = first, }; }; };
Editor Settings
Theme
Key bindings
Full width
Lines