HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
text_cursor.hpp
1// Copyright Take Vos 2022.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "../required.hpp"
8#include "../assert.hpp"
9#include "../math.hpp"
10#include "../cast.hpp"
11#include "../unicode/unicode_description.hpp"
12#include <tuple>
13#include <cstdlib>
14#include <algorithm>
15
16namespace hi::inline v1 {
17
19public:
20 constexpr text_cursor() noexcept : _value(0) {}
21 constexpr text_cursor(text_cursor const &) noexcept = default;
22 constexpr text_cursor(text_cursor &&) noexcept = default;
23 constexpr text_cursor &operator=(text_cursor const &) noexcept = default;
24 constexpr text_cursor &operator=(text_cursor &&) noexcept = default;
25
32 constexpr text_cursor(size_t index, bool after, size_t size) noexcept
33 {
34 if (size == 0) {
35 // Special case, when size is zero, the cursor is before the non-existing first character.
36 index = 0;
37 after = false;
38 } else if (static_cast<ptrdiff_t>(index) < 0) {
39 // Underflow.
40 index = 0;
41 after = false;
42 } else if (index >= size) {
43 // Overflow.
44 index = size - 1;
45 after = true;
46 }
47
48 _value = (index << 1) | static_cast<size_t>(after);
49 }
50
57 [[nodiscard]] constexpr text_cursor neighbor(size_t size) const noexcept
58 {
59 if (before()) {
60 return {index() - 1, true, size};
61 } else {
62 return {index() + 1, false, size};
63 }
64 }
65
66 [[nodiscard]] constexpr text_cursor after_neighbor(size_t size) const noexcept
67 {
68 return before() ? neighbor(size) : *this;
69 }
70
71 [[nodiscard]] constexpr text_cursor before_neighbor(size_t size) const noexcept
72 {
73 return after() ? neighbor(size) : *this;
74 }
75
76 [[nodiscard]] constexpr bool start_of_text() const noexcept
77 {
78 return _value == 0;
79 }
80
81 [[nodiscard]] constexpr bool end_of_text(size_t size) const noexcept
82 {
83 return size == 0 or (index() == size - 1 and after()) or index() >= size;
84 }
85
86 [[nodiscard]] constexpr size_t index() const noexcept
87 {
88 return _value >> 1;
89 }
90
91 [[nodiscard]] constexpr bool after() const noexcept
92 {
93 return static_cast<bool>(_value & 1);
94 }
95
96 [[nodiscard]] constexpr bool before() const noexcept
97 {
98 return not after();
99 }
100
101 [[nodiscard]] constexpr friend bool operator==(text_cursor const &, text_cursor const &) = default;
102 [[nodiscard]] constexpr friend auto operator<=>(text_cursor const &, text_cursor const &) = default;
103
104private:
105 size_t _value;
106};
107
108} // namespace hi::inline v1
This file includes required definitions.
Definition text_cursor.hpp:18
constexpr text_cursor neighbor(size_t size) const noexcept
Return the neighbor cursor.
Definition text_cursor.hpp:57
constexpr text_cursor(size_t index, bool after, size_t size) noexcept
Create a new text cursor.
Definition text_cursor.hpp:32