diff options
author | Jacques Lucke <jacques@blender.org> | 2020-06-09 11:10:56 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-06-09 11:15:43 +0300 |
commit | d8678e02ecec9375bec1dcf1388c6fc8b4ce3ad2 (patch) | |
tree | 6e7d2a7452091877f73d413d830e6cb12e86745f /source/blender/blenlib/BLI_index_range.hh | |
parent | 50258d55e7c1360274d40e303386cf70b16c8b2f (diff) |
BLI: generally improve C++ data structures
The main focus here was to improve the docs significantly. Furthermore,
I reimplemented `Set`, `Map` and `VectorSet`. They are now (usually)
faster, simpler and more customizable. I also rewrote `Stack` to make
it more efficient by avoiding unnecessary copies.
Thanks to everyone who helped with constructive feedback.
Approved by brecht and sybren.
Differential Revision: https://developer.blender.org/D7931
Diffstat (limited to 'source/blender/blenlib/BLI_index_range.hh')
-rw-r--r-- | source/blender/blenlib/BLI_index_range.hh | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/source/blender/blenlib/BLI_index_range.hh b/source/blender/blenlib/BLI_index_range.hh index e24fd567810..4a64ae16589 100644 --- a/source/blender/blenlib/BLI_index_range.hh +++ b/source/blender/blenlib/BLI_index_range.hh @@ -20,9 +20,37 @@ /** \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. + * A `BLI::IndexRange` wraps an interval of non-negative integers. It can be used to reference + * consecutive elements in an array. Furthermore, it can make for loops more convenient and less + * error prone, especially when using nested loops. + * + * I'd argue that the second loop is more readable and less error prone than the first one. That is + * not necessarily always the case, but often it is. + * + * for (uint i = 0; i < 10; i++) { + * for (uint j = 0; j < 20; j++) { + * for (uint k = 0; k < 30; k++) { + * + * for (uint i : IndexRange(10)) { + * for (uint j : IndexRange(20)) { + * for (uint k : IndexRange(30)) { + * + * Some containers like BLI::Vector have an index_range() method. This will return the IndexRange + * that contains all indices that can be used to access the container. This is particularly useful + * when you want to iterate over the indices and the elements (much like Python's enumerate(), just + * worse). Again, I think the second example here is better: + * + * for (uint i = 0; i < my_vector_with_a_long_name.size(); i++) { + * do_something(i, my_vector_with_a_long_name[i]); + * + * for (uint i : my_vector_with_a_long_name.index_range()) { + * do_something(i, my_vector_with_a_long_name[i]); + * + * Ideally this could be could be even closer to Python's enumerate(). We might get that in the + * future with newer C++ versions. + * + * One other important feature is the as_array_ref method. This method returns an ArrayRef<uint> + * that contains the interval as individual numbers. */ #include <algorithm> @@ -182,13 +210,15 @@ class IndexRange { return value >= m_start && value < m_start + m_size; } + /** + * Returns a new range, that contains a subinterval of the current one. + */ 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()); |