summaryrefslogtreecommitdiff
path: root/point.cpp
diff options
context:
space:
mode:
authorJuan Manuel Tomás <jtomas1815@gmail.com>2020-05-24 05:35:00 -0300
committerJuan Manuel Tomás <jtomas1815@gmail.com>2020-05-24 05:35:00 -0300
commit98280238383dc390207827d09dc92e0459229134 (patch)
treee2bc7c0877289165463dd6f9c2e77b570b22e29c /point.cpp
parentd37027bbd7ac13fdd0f1e2f01e1ec4b75b6c9588 (diff)
downloadjet-98280238383dc390207827d09dc92e0459229134.tar.gz
jet-98280238383dc390207827d09dc92e0459229134.zip
Rewrite in c++
Diffstat (limited to 'point.cpp')
-rw-r--r--point.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/point.cpp b/point.cpp
new file mode 100644
index 0000000..e31f5de
--- /dev/null
+++ b/point.cpp
@@ -0,0 +1,112 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+struct Point {
+ Page *page;
+ uint16_t index;
+
+ Point() : page(nullptr), index(0) {}
+ Point(Page *page) : page(page), index(0) {}
+ Point(const Point& p) : page(p.page), index(p.index) {}
+
+ uint16_t index_to_offset() {
+ if (index < page->gap_start) {
+ return index;
+ } else {
+ return index + (page->gap_end - page->gap_start);
+ }
+ }
+
+ bool operator==(Point p) {
+ return page == p.page && index == p.index;
+ }
+
+ uint8_t element() {
+ if (index == page->element_count) {
+ return !page->next ? 0 : page->next->elements[0];
+ } else {
+ return page->elements[index_to_offset()];
+ }
+ }
+
+ void operator++(int) {
+ if (index < page->element_count) {
+ index++;
+ } else if (page->next) {
+ index = 1;
+ page = page->next;
+ }
+ }
+
+ void operator--(int) {
+ if (index > 1) {
+ index--;
+ } else if (page->prev) {
+ page = page->prev;
+ index = page->element_count;
+ } else {
+ index = 0;
+ }
+ }
+
+ uint64_t seek(uint8_t c, uint64_t limit) {
+ uint64_t travel_distance = 0;
+ while (element() && element() != c && travel_distance < limit) {
+ (*this)++;
+ travel_distance++;
+ }
+ return travel_distance;
+ }
+
+ uint64_t rseek(uint8_t c, uint64_t limit) {
+ uint64_t travel_distance = 0;
+ while (index != 0 && element() != c && travel_distance < limit) {
+ (*this)--;
+ travel_distance++;
+ }
+ return travel_distance;
+ }
+
+ void align_gap() {
+ while (page->gap_end < index_to_offset()) {
+ (*page)++;
+ }
+ while (page->gap_end > index_to_offset()) {
+ (*page)--;
+ }
+ }
+
+ void push(uint8_t c) {
+ if (page->gap_start == page->gap_end) {
+ page->split();
+ if (index >= PAGE_SIZE / 2) {
+ page = page->next;
+ index -= PAGE_SIZE / 2;
+ }
+ }
+ align_gap();
+ page->push(c);
+ (*this)++;
+ }
+
+ void pop() {
+ if (page->element_count == 1 && index == 1) {
+ if (page->prev) {
+ (*this)--;
+ delete page->next;
+ } else if (page->next) {
+ page->next->copy_to(page);
+ delete page->next;
+ index = 0;
+ } else {
+ page->pop();
+ index = 0;
+ }
+ } else if (index > 0) {
+ align_gap();
+ page->pop();
+ (*this)--;
+ }
+ }
+
+};