Lagrange
range.h
1/*
2 * Copyright 2019 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <lagrange/utils/safe_cast.h>
15
18
19namespace lagrange {
20
23
24namespace internal {
25
26template <typename T>
27struct IteratorTrait
28{
29 using iterator_category = std::input_iterator_tag;
30 using value_type = T;
31 using difference_type = std::ptrdiff_t; // Not used.
32 using pointer = T*;
33 using reference = T&;
34};
35
36template <typename T, typename Trait = IteratorTrait<T>>
37class Range
38{
39public:
40 Range(T end)
41 : m_begin(0)
42 , m_end(end)
43 {}
44 Range(T begin, T end)
45 : m_begin(begin)
46 , m_end(end)
47 {}
48
49 class iterator
50 {
51 public:
52 using iterator_category = typename Trait::iterator_category;
53 using value_type = typename Trait::value_type;
54 using difference_type = typename Trait::difference_type;
55 using pointer = typename Trait::pointer;
56 using reference = typename Trait::reference;
57
58 public:
59 explicit iterator(T val, const Range<T>& c)
60 : m_value(val)
61 , m_context(c)
62 {}
63
64 const T& operator*() const { return m_value; }
65
66 iterator& operator++()
67 {
68 ++m_value;
69 return *this;
70 }
71
72 bool operator!=(const iterator other) const
73 {
74 if (m_context == other.m_context) {
75 return m_value < other.m_value;
76 } else {
77 return true;
78 }
79 }
80
81 private:
82 T m_value;
83 const Range<T>& m_context;
84 };
85
86 iterator begin() const { return iterator(m_begin, *this); }
87
88 iterator end() const { return iterator(m_end, *this); }
89
90 bool operator==(const Range<T>& other) const
91 {
92 return m_begin == other.m_begin && m_end == other.m_end;
93 }
94
95private:
96 T m_begin;
97 T m_end;
98};
99
100template <typename T, typename Trait = IteratorTrait<T>>
101class SparseRange
102{
103 const T m_max;
104 const std::vector<T>& m_active;
105
106public:
107 SparseRange(T max, const std::vector<T>& active)
108 : m_max(max)
109 , m_active(active)
110 {}
111
112 class iterator
113 {
114 public:
115 using iterator_category = typename Trait::iterator_category;
116 using value_type = typename Trait::value_type;
117 using difference_type = typename Trait::difference_type;
118 using pointer = typename Trait::pointer;
119 using reference = typename Trait::reference;
120
121 public:
122 iterator(T val, const SparseRange& context)
123 : m_context(context)
124 , i(val)
125 {}
126
127 bool operator!=(const iterator& rhs) const
128 {
129 return (m_context != rhs.m_context) || (i != rhs.i);
130 }
131
132 iterator& operator++()
133 {
134 ++i;
135 return *this;
136 }
137
138 T operator*() const
139 {
140 if (m_context.m_active.empty()) return i;
141 return m_context.m_active[i];
142 }
143
144 private:
145 const SparseRange& m_context;
146 T i;
147 };
148
149 iterator begin() const { return iterator(0, *this); }
150 iterator end() const
151 {
152 return iterator(m_active.empty() ? m_max : safe_cast<T>(m_active.size()), *this);
153 }
154
155 bool operator!=(const SparseRange<T> other) const
156 {
157 return m_max != other.m_max || m_active.size() != other.m_active.size();
158 }
159};
160
161} // namespace internal
162
165
175template <typename Index>
176internal::Range<Index> range(Index end)
177{
178 return internal::Range<Index>(end);
179}
180
191template <typename Index>
192internal::Range<Index> range(Index begin, Index end)
193{
194 return internal::Range<Index>(begin, end);
195}
196
216template <typename Index>
217internal::SparseRange<Index> range_sparse(Index max, const std::vector<Index>& active)
218{
219 return internal::SparseRange<Index>(max, active);
220}
221
227template <typename T>
228internal::SparseRange<T> range_sparse(T /*max*/, std::vector<T>&& /*active*/) = delete;
230
231} // namespace lagrange
internal::SparseRange< Index > range_sparse(Index max, const std::vector< Index > &active)
Returns an iterable object representing a subset of the range [0, max).
Definition: range.h:217
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition: range.h:176
bool operator==(const shared_ptr< T > &sp1, const shared_ptr< U > &sp2)
Operator == overloading.
Definition: shared_ptr.h:344
bool operator!=(const shared_ptr< T > &sp1, const shared_ptr< U > &sp2)
Operator != overloading.
Definition: shared_ptr.h:363
Main namespace for Lagrange.
Definition: AABBIGL.h:30