VisuTwin Canvas
C++ 3D Engine — Metal Backend
Loading...
Searching...
No Matches
sortedLoopArray.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2025-2026 Arnis Lektauers
3#pragma once
4
5#include <algorithm>
6#include <functional>
7#include <vector>
8
9namespace visutwin::canvas
10{
11 template<typename T>
13 {
14 std::function<float(const T&)> keyExtractor;
15 };
16
17 template<typename T>
19 {
20 public:
22 : _keyExtractor(options.keyExtractor) {}
23
24 explicit SortedLoopArray(std::function<float(const T&)> keyExtractor)
25 : _keyExtractor(std::move(keyExtractor))
26 {
27 }
28
29 std::vector<T> items;
30 size_t length = 0;
31 int loopIndex = -1;
32
33 void insert(const T& item)
34 {
35 const int index = binarySearch(item);
36 items.insert(items.begin() + index, item);
37 length = items.size();
38 if (loopIndex >= index) {
39 loopIndex++;
40 }
41 }
42
43 void append(const T& item)
44 {
45 items.push_back(item);
46 length = items.size();
47 }
48
49 void remove(const T& item)
50 {
51 const auto it = std::find(items.begin(), items.end(), item);
52 if (it == items.end()) {
53 return;
54 }
55
56 const int index = static_cast<int>(std::distance(items.begin(), it));
57 items.erase(it);
58 length = items.size();
59 if (loopIndex >= index) {
60 loopIndex--;
61 }
62 }
63
64 void sort()
65 {
66 T current{};
67 bool hasCurrent = loopIndex >= 0 && loopIndex < static_cast<int>(items.size());
68 if (hasCurrent) {
69 current = items[loopIndex];
70 }
71
72 std::sort(items.begin(), items.end(), [&](const T& a, const T& b) {
73 return _keyExtractor(a) < _keyExtractor(b);
74 });
75
76 if (hasCurrent) {
77 auto it = std::find(items.begin(), items.end(), current);
78 loopIndex = (it == items.end()) ? -1 : static_cast<int>(std::distance(items.begin(), it));
79 }
80
81 length = items.size();
82 }
83
84 private:
85 int binarySearch(const T& item) const
86 {
87 int left = 0;
88 int right = static_cast<int>(items.size()) - 1;
89 const float key = _keyExtractor(item);
90
91 while (left <= right) {
92 const int middle = (left + right) / 2;
93 const float current = _keyExtractor(items[middle]);
94 if (current <= key) {
95 left = middle + 1;
96 } else {
97 right = middle - 1;
98 }
99 }
100
101 return left;
102 }
103
104 std::function<float(const T&)> _keyExtractor;
105 };
106}
SortedLoopArray(std::function< float(const T &)> keyExtractor)
SortedLoopArray(const SortedLoopArrayOptions< T > &options)
std::function< float(const T &)> keyExtractor