Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-04-21 18:31:56 +0300
committerJacques Lucke <jacques@blender.org>2020-04-21 18:31:56 +0300
commit3059353b38ed1fc432cce584afad5bef3b7f2227 (patch)
tree7b0fe042cccc6a3372ecb379e2d1725dea6515a9 /source/blender/blenlib/BLI_index_range.hh
parent0e52b91f97bcb800dc4f07f93f7f07e1cf9cab1c (diff)
BLI: Use .hh extension for C++ headers in blenlib
Diffstat (limited to 'source/blender/blenlib/BLI_index_range.hh')
-rw-r--r--source/blender/blenlib/BLI_index_range.hh211
1 files changed, 211 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh
new file mode 100644
index 00000000000..e24fd567810
--- /dev/null
+++ b/source/blender/blenlib/BLI_index_range.hh
@@ -0,0 +1,211 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __BLI_INDEX_RANGE_HH__
+#define __BLI_INDEX_RANGE_HH__
+
+/** \file
+ * \ingroup bli
+ *
+ * Allows passing iterators over ranges of integers without actually allocating an array or passing
+ * separate values. A range always has a step of one. If other step sizes are required in some
+ * cases, a separate data structure should be used.
+ */
+
+#include <algorithm>
+#include <cmath>
+#include <iostream>
+
+#include "BLI_utildefines.h"
+
+/* Forward declare tbb::blocked_range for conversion operations. */
+namespace tbb {
+template<typename Value> class blocked_range;
+}
+
+namespace BLI {
+
+template<typename T> class ArrayRef;
+
+class IndexRange {
+ private:
+ uint m_start = 0;
+ uint m_size = 0;
+
+ public:
+ IndexRange() = default;
+
+ explicit IndexRange(uint size) : m_start(0), m_size(size)
+ {
+ }
+
+ IndexRange(uint start, uint size) : m_start(start), m_size(size)
+ {
+ }
+
+ template<typename T>
+ IndexRange(const tbb::blocked_range<T> &range) : m_start(range.begin()), m_size(range.size())
+ {
+ }
+
+ class Iterator {
+ private:
+ uint m_current;
+
+ public:
+ Iterator(uint current) : m_current(current)
+ {
+ }
+
+ Iterator &operator++()
+ {
+ m_current++;
+ return *this;
+ }
+
+ bool operator!=(const Iterator &iterator) const
+ {
+ return m_current != iterator.m_current;
+ }
+
+ uint operator*() const
+ {
+ return m_current;
+ }
+ };
+
+ Iterator begin() const
+ {
+ return Iterator(m_start);
+ }
+
+ Iterator end() const
+ {
+ return Iterator(m_start + m_size);
+ }
+
+ /**
+ * Access an element in the range.
+ */
+ uint operator[](uint index) const
+ {
+ BLI_assert(index < this->size());
+ return m_start + index;
+ }
+
+ /**
+ * Two ranges compare equal when they contain the same numbers.
+ */
+ friend bool operator==(IndexRange a, IndexRange b)
+ {
+ return (a.m_size == b.m_size) && (a.m_start == b.m_start || a.m_size == 0);
+ }
+
+ /**
+ * Get the amount of numbers in the range.
+ */
+ uint size() const
+ {
+ return m_size;
+ }
+
+ /**
+ * Create a new range starting at the end of the current one.
+ */
+ IndexRange after(uint n) const
+ {
+ return IndexRange(m_start + m_size, n);
+ }
+
+ /**
+ * Create a new range that ends at the start of the current one.
+ */
+ IndexRange before(uint n) const
+ {
+ return IndexRange(m_start - n, n);
+ }
+
+ /**
+ * Get the first element in the range.
+ * Asserts when the range is empty.
+ */
+ uint first() const
+ {
+ BLI_assert(this->size() > 0);
+ return m_start;
+ }
+
+ /**
+ * Get the last element in the range.
+ * Asserts when the range is empty.
+ */
+ uint last() const
+ {
+ BLI_assert(this->size() > 0);
+ return m_start + m_size - 1;
+ }
+
+ /**
+ * Get the element one after the end. The returned value is undefined when the range is empty.
+ */
+ uint one_after_last() const
+ {
+ return m_start + m_size;
+ }
+
+ /**
+ * Get the first element in the range. The returned value is undefined when the range is empty.
+ */
+ uint start() const
+ {
+ return m_start;
+ }
+
+ /**
+ * Returns true when the range contains a certain number, otherwise false.
+ */
+ bool contains(uint value) const
+ {
+ return value >= m_start && value < m_start + m_size;
+ }
+
+ IndexRange slice(uint start, uint size) const
+ {
+ uint new_start = m_start + start;
+ BLI_assert(new_start + size <= m_start + m_size || size == 0);
+ return IndexRange(new_start, size);
+ }
+
+ IndexRange slice(IndexRange range) const
+ {
+ return this->slice(range.start(), range.size());
+ }
+
+ /**
+ * Get read-only access to a memory buffer that contains the range as actual numbers.
+ */
+ ArrayRef<uint> as_array_ref() const;
+
+ friend std::ostream &operator<<(std::ostream &stream, IndexRange range)
+ {
+ stream << "[" << range.start() << ", " << range.one_after_last() << ")";
+ return stream;
+ }
+};
+
+} // namespace BLI
+
+#endif /* __BLI_INDEX_RANGE_HH__ */