tesseract++ 0.0.1
N-dimensional tensor library for embedded systems
Loading...
Searching...
No Matches
sparse_access.h
Go to the documentation of this file.
1#ifndef SPARSE_ACCESS_H
2#define SPARSE_ACCESS_H
3
5#include "memory/mem_utils.h"
6#include "simple_type_traits.h" // for move
7
8template <
9 typename T,
10 my_size_t NonZeroCount,
11 typename IndexType = my_size_t,
12 template <typename, my_size_t> class ValueStoragePolicy = StaticStorage,
13 template <typename, my_size_t> class IndexStoragePolicy = StaticStorage>
15{
16 ValueStoragePolicy<T, NonZeroCount> values_; // Nonzero values
17 IndexStoragePolicy<IndexType, NonZeroCount> indices_; // Flat indices
18
19 my_size_t current_size_ = 0;
20 mutable my_size_t last_idx_ = 0; // track last successful search
21
22 // Dummy zero for failed reference returns (only used if overflow occurs)
23 T dummy_zero_ = T(0);
24
25public:
27 {
28 fill_n_optimized(indices_.data(), NonZeroCount, IndexType(-1));
29 }
30
31 SparseAccess(T initValue)
32 {
33 for (my_size_t i = 0; i < NonZeroCount; ++i) // assume that
34 {
35 this->operator[](i) = initValue;
36 }
37 }
38
39 // Copy constructor
41 : values_(other.values_), indices_(other.indices_), current_size_(other.current_size_)
42 {
43 }
44
45 // Move constructor
46 SparseAccess(SparseAccess &&other) noexcept
47 : values_(move(other.values_)), indices_(move(other.indices_)), current_size_(other.current_size_)
48 {
49 other.current_size_ = 0; // only reset logical size
50 }
51
52 // Copy assignment
54 {
55 if (this != &other)
56 {
57 values_ = other.values_;
58 indices_ = other.indices_;
59 current_size_ = other.current_size_;
60 last_idx_ = 0; // keep — old cache is stale
61 }
62 return *this;
63 }
64
65 // Move assignment
67 {
68 if (this != &other)
69 {
70 values_ = move(other.values_);
71 indices_ = move(other.indices_);
72 current_size_ = other.current_size_;
73 last_idx_ = 0; // keep — old cache is stale
74 other.current_size_ = 0;
75 }
76 return *this;
77 }
78
79 // print the sparse representation
80 void print() const
81 {
82 std::cout << "Sparse Representation (NonZeroCount = " << NonZeroCount << "):\n";
83 for (my_size_t i = 0; i < current_size_; ++i)
84 {
85 std::cout << "Index: " << indices_[i] << ", Value: " << values_[i] << "\n";
86 }
87 }
88
89 // Iterators for values
90 FORCE_INLINE constexpr T *data() noexcept { return values_.data(); }
91 FORCE_INLINE constexpr const T *data() const noexcept { return values_.data(); }
92 FORCE_INLINE constexpr T *values_begin() noexcept { return values_.begin(); }
93 FORCE_INLINE constexpr const T *values_begin() const noexcept { return values_.begin(); }
94 FORCE_INLINE constexpr T *values_end() noexcept { return values_.end(); }
95 FORCE_INLINE constexpr const T *values_end() const noexcept { return values_.end(); }
96
97 // Iterators for indices
98 FORCE_INLINE constexpr IndexType *indices_data() noexcept { return indices_.data(); }
99 FORCE_INLINE constexpr const IndexType *indices_data() const noexcept { return indices_.data(); }
100 FORCE_INLINE constexpr IndexType *indices_begin() noexcept { return indices_.begin(); }
101 FORCE_INLINE constexpr const IndexType *indices_begin() const noexcept { return indices_.begin(); }
102 FORCE_INLINE constexpr IndexType *indices_end() noexcept { return indices_.end(); }
103 FORCE_INLINE constexpr const IndexType *indices_end() const noexcept { return indices_.end(); }
104
105 // Number of nonzero elements
106 // static constexpr my_size_t size() noexcept { return NonZeroCount; }
107
108 // Dense-style operator[] returning reference for assignment
109 FORCE_INLINE T &operator[](IndexType idx) noexcept
110 {
111 // Check if index already exists
112 for (my_size_t i = 0; i < current_size_; ++i)
113 {
114 if (indices_[i] == idx)
115 return values_[i];
116 }
117
118 // Not found: insert if space available
119 if (current_size_ < NonZeroCount)
120 {
121 indices_[current_size_] = idx;
122 values_[current_size_] = T{}; // initialize to zero
123 ++current_size_;
124 return values_[current_size_ - 1];
125 }
126
127 // If full, return reference to dummy_zero_
128 MyErrorHandler::error("SparseAccess: exceeded NonZeroCount capacity!");
129 return dummy_zero_;
130 }
131
132 // Const operator[] for read-only access
133 FORCE_INLINE const T &operator[](IndexType idx) const noexcept
134 {
135 // Check the last accessed first
136 if (last_idx_ < current_size_ && indices_[last_idx_] == idx)
137 return values_[last_idx_];
138
139 for (my_size_t i = 0; i < current_size_; ++i)
140 {
141 if (indices_[i] == idx)
142 {
143 last_idx_ = i;
144 return values_[i];
145 }
146 }
147 return dummy_zero_;
148 }
149};
150
151#endif // SPARSE_ACCESS_H
static void error(const T &msg)
Definition error_handler.h:30
Definition sparse_access.h:15
FORCE_INLINE T & operator[](IndexType idx) noexcept
Definition sparse_access.h:109
FORCE_INLINE constexpr const T * data() const noexcept
Definition sparse_access.h:91
FORCE_INLINE constexpr T * data() noexcept
Definition sparse_access.h:90
FORCE_INLINE constexpr T * values_begin() noexcept
Definition sparse_access.h:92
FORCE_INLINE constexpr IndexType * indices_end() noexcept
Definition sparse_access.h:102
SparseAccess(SparseAccess &&other) noexcept
Definition sparse_access.h:46
FORCE_INLINE const T & operator[](IndexType idx) const noexcept
Definition sparse_access.h:133
SparseAccess(const SparseAccess &other)
Definition sparse_access.h:40
FORCE_INLINE constexpr const IndexType * indices_data() const noexcept
Definition sparse_access.h:99
FORCE_INLINE constexpr IndexType * indices_begin() noexcept
Definition sparse_access.h:100
SparseAccess(T initValue)
Definition sparse_access.h:31
SparseAccess & operator=(const SparseAccess &other)
Definition sparse_access.h:53
FORCE_INLINE constexpr const T * values_begin() const noexcept
Definition sparse_access.h:93
SparseAccess()
Definition sparse_access.h:26
FORCE_INLINE constexpr IndexType * indices_data() noexcept
Definition sparse_access.h:98
SparseAccess & operator=(SparseAccess &&other) noexcept
Definition sparse_access.h:66
void print() const
Definition sparse_access.h:80
FORCE_INLINE constexpr const IndexType * indices_begin() const noexcept
Definition sparse_access.h:101
FORCE_INLINE constexpr const T * values_end() const noexcept
Definition sparse_access.h:95
FORCE_INLINE constexpr const IndexType * indices_end() const noexcept
Definition sparse_access.h:103
FORCE_INLINE constexpr T * values_end() noexcept
Definition sparse_access.h:94
Definition static_storage.h:9
#define my_size_t
Size/index type used throughout the library.
Definition config.h:126
#define FORCE_INLINE
Hint the compiler to always inline a function.
Definition config.h:26
STL-free memory utilities.
void fill_n_optimized(T *ptr, my_size_t count, const T &value)
Fill a contiguous buffer with a given value.
Definition mem_utils.h:71
constexpr remove_reference_t< T > && move(T &&t) noexcept
Cast to rvalue reference (replacement for std::move).
Definition simple_type_traits.h:178