ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkPriorityQueueContainer.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkPriorityQueueContainer_h
19#define itkPriorityQueueContainer_h
20
21#include "itkVectorContainer.h"
22#include "itkIntTypes.h"
23#include "itkNumericTraits.h"
24
25#include <functional>
26#include <queue>
27#include <vector>
28
29namespace itk
30{
31// first define a common interface all the wrapper will have to abide to
32// this will let us define our own wrapper with different behavior.
33// As an example we define below a wrapper for a min sorted or max sorted
34// queue.
35template <typename TElement, typename TElementIdentifier = IdentifierType>
36class ITK_TEMPLATE_EXPORT ElementWrapperInterface
37{
38public:
39 using ElementType = TElement;
40 using ElementIdentifierType = TElementIdentifier;
41
43
45 virtual ~ElementWrapperInterface() = default;
47
48 [[nodiscard]] virtual ElementIdentifierType
49 GetLocation(const ElementType & element) const = 0;
50
51 virtual void
52 SetLocation(ElementType & element, const ElementIdentifierType & identifier) = 0;
53
54 [[nodiscard]] virtual bool
55 is_less(const ElementType & element1, const ElementType & element2) const = 0;
56
57 [[nodiscard]] virtual bool
58 is_greater(const ElementType & element1, const ElementType & element2) const = 0;
59};
60// ------------------------------------------------------------------------
61
62
63// ------------------------------------------------------------------------
64// If you want to manage the items outside the queue for example, if you don't
65// want the queue to manage the items memory, then you can use this wrapper
66// around pointers to items. It follows the ElementWrapperInterface and thus
67// can be used in the queue.
68//
69template <typename TElementWrapperPointer, typename TElementIdentifier = IdentifierType>
70class ITK_TEMPLATE_EXPORT ElementWrapperPointerInterface
71{
72public:
73 using ElementWrapperPointerType = TElementWrapperPointer;
74 using ElementIdentifierType = TElementIdentifier;
75
77
81
82 TElementIdentifier
83 GetLocation(const ElementWrapperPointerType & element) const;
84
85 void
87
88 virtual bool
89 is_less(const ElementWrapperPointerType & element1, const ElementWrapperPointerType & element2) const;
90
91 virtual bool
92 is_greater(const ElementWrapperPointerType & element1, const ElementWrapperPointerType & element2) const;
93};
94// ------------------------------------------------------------------------
95
96// ------------------------------------------------------------------------
97// To follow ITK rule, we template the ElementWrapperType priority and the element
98// identifier type.
99// For example, as we want to use this for decimation, the element will be some
100// kind of cell or point pointer, the priority will be whatever you want it to
101// be as long as you define the comparison operators, and the identifier will
102// set according to the size of the vector you want to create.
103//
104// this implementation is used for min sorted priorityqueue
105template <typename TElement, typename TElementPriority = double, typename TElementIdentifier = IdentifierType>
106class ITK_TEMPLATE_EXPORT MinPriorityQueueElementWrapper
107 : public ElementWrapperInterface<MinPriorityQueueElementWrapper<TElement, TElementPriority, TElementIdentifier>,
108 TElementIdentifier>
109{
110public:
112 using ElementType = TElement;
113 using ElementPriorityType = TElementPriority;
114 using ElementIdentifierType = TElementIdentifier;
115
119
121
123
124 bool
126
127 bool
128 operator<(const MinPriorityQueueElementWrapper & other) const;
129
130 bool
132
134 GetLocation(const MinPriorityQueueElementWrapper & element) const override;
135
136 void
137 SetLocation(MinPriorityQueueElementWrapper & element, const ElementIdentifierType & identifier) override;
138
139 // still virtual to be able to overload it in the Max flavor
140 bool
142 const MinPriorityQueueElementWrapper & element2) const override;
143
144 bool
146 const MinPriorityQueueElementWrapper & element2) const override;
147};
148// ------------------------------------------------------------------------
149
150
151// ------------------------------------------------------------------------
152// this implementation is used for max sorted priorityqueue
153// most of the job is already done, just need to overload the less
154// and greater ops.
155template <typename TElement, typename TElementPriority = double, typename TElementIdentifier = IdentifierType>
156class ITK_TEMPLATE_EXPORT MaxPriorityQueueElementWrapper
157 : public MinPriorityQueueElementWrapper<TElement, TElementPriority, TElementIdentifier>
158{
159public:
160 using ElementType = TElement;
161 using ElementPriorityType = TElementPriority;
162 using ElementIdentifierType = TElementIdentifier;
163
166
168
169 virtual bool
171
172 bool
173 is_less(const Superclass & element1, const Superclass & element2) const override;
174
175 virtual bool
177
178 bool
179 is_greater(const Superclass & element1, const Superclass & element2) const override;
180};
181// ------------------------------------------------------------------------
182
183
184// ------------------------------------------------------------------------
185// finally, implement the priority queue itself on top of an
186// itk::VectorContainer
187template <typename TElementWrapper,
188 typename TElementWrapperInterface,
189 typename TElementPriority = double,
190 typename TElementIdentifier = IdentifierType>
191class ITK_TEMPLATE_EXPORT PriorityQueueContainer : public VectorContainer<TElementIdentifier, TElementWrapper>
192{
193public:
198
199 using ElementIdentifierType = TElementIdentifier;
200 using ElementWrapperType = TElementWrapper;
201 using ElementInterfaceType = TElementWrapperInterface;
202
204
205public:
207 ~PriorityQueueContainer() override = default;
208
209 template <typename TInputIterator>
210 PriorityQueueContainer(TInputIterator first, TInputIterator last)
211 : Superclass()
212 {
213 TInputIterator it = first;
214 while (it != last)
215 {
216 this->Push(*it);
217 ++it;
218 }
219 }
220
221public:
222 itkNewMacro(Self);
223 itkOverrideGetNameOfClassMacro(PriorityQueueContainer);
224
225 // void Reserve( ElementIdentifier NbOfElementsToStore )
226 //{ this->Superclass->Reserve( NbOfElementsToStore ); }
227 // void Squeeze( ) { this->Superclass->Squeeze( ); }
228 void
230 [[nodiscard]] bool
231 Empty() const;
232 void
234
235 const ElementWrapperType &
236 Peek() const;
237
238 void
240
244 bool
245 Update(const ElementWrapperType & element);
246
250 bool
252
253protected:
254 // One instance of the interface to deal with the functions calls
256
257 inline ElementWrapperType &
259 {
260 return this->operator[](identifier);
261 }
262
263 inline const ElementWrapperType &
265 {
266 return this->operator[](identifier);
267 }
268
269 inline void
271 {
272 this->operator[](identifier) = element;
273 m_Interface.SetLocation(element, identifier);
274 }
275
276 inline ElementIdentifierType
277 GetParent(const ElementIdentifierType & identifier) const
278 {
279 return (identifier - 1) >> 1;
280 }
281
282 inline ElementIdentifierType
283 GetLeft(const ElementIdentifierType & identifier) const
284 {
285 return (identifier << 1) + 1;
286 }
287
288 inline ElementIdentifierType
289 GetRight(const ElementIdentifierType & identifier) const
290 {
291 return (identifier << 1) + 2;
292 }
293
294 inline bool
296 {
297 return iId > 0;
298 }
299
300 void
302
303
304 void
306};
307// ------------------------------------------------------------------------
308
309} // namespace itk
310
311#include "itkPriorityQueueContainer.hxx"
312#endif
static const ElementIdentifierType m_ElementNotFound
virtual bool is_greater(const ElementType &element1, const ElementType &element2) const =0
virtual ~ElementWrapperInterface()=default
ITK_DEFAULT_COPY_AND_MOVE(ElementWrapperInterface)
virtual void SetLocation(ElementType &element, const ElementIdentifierType &identifier)=0
virtual bool is_less(const ElementType &element1, const ElementType &element2) const =0
virtual ElementIdentifierType GetLocation(const ElementType &element) const =0
virtual ~ElementWrapperPointerInterface()=default
ITK_DEFAULT_COPY_AND_MOVE(ElementWrapperPointerInterface)
virtual bool is_less(const ElementWrapperPointerType &element1, const ElementWrapperPointerType &element2) const
void SetLocation(ElementWrapperPointerType &element, const ElementIdentifierType &identifier)
TElementIdentifier GetLocation(const ElementWrapperPointerType &element) const
virtual bool is_greater(const ElementWrapperPointerType &element1, const ElementWrapperPointerType &element2) const
static const ElementIdentifierType m_ElementNotFound
bool is_greater(const Superclass &element1, const Superclass &element2) const override
MinPriorityQueueElementWrapper< ElementType, ElementPriorityType, ElementIdentifierType > Superclass
bool is_less(const Superclass &element1, const Superclass &element2) const override
MaxPriorityQueueElementWrapper(ElementType element, ElementPriorityType priority)
virtual bool is_greater(const MaxPriorityQueueElementWrapper &element1, const MaxPriorityQueueElementWrapper &element2) const
virtual bool is_less(const MaxPriorityQueueElementWrapper &element1, const MaxPriorityQueueElementWrapper &element2) const
bool is_greater(const MinPriorityQueueElementWrapper &element1, const MinPriorityQueueElementWrapper &element2) const override
bool operator>(const MinPriorityQueueElementWrapper &other) const
bool operator==(const MinPriorityQueueElementWrapper &other) const
bool is_less(const MinPriorityQueueElementWrapper &element1, const MinPriorityQueueElementWrapper &element2) const override
bool operator<(const MinPriorityQueueElementWrapper &other) const
MinPriorityQueueElementWrapper< TElement, TElementPriority, TElementIdentifier > Superclass
ElementIdentifierType GetLocation(const MinPriorityQueueElementWrapper &element) const override
void SetLocation(MinPriorityQueueElementWrapper &element, const ElementIdentifierType &identifier) override
MinPriorityQueueElementWrapper(ElementType element, ElementPriorityType priority)
ElementWrapperType & GetElementAtLocation(const ElementIdentifierType &identifier)
void UpdateDownTree(const ElementIdentifierType &identifier)
TElementWrapperInterface ElementInterfaceType
ElementIdentifierType GetParent(const ElementIdentifierType &identifier) const
SmartPointer< const Self > ConstPointer
VectorContainer< TElementIdentifier, TElementWrapper > Superclass
bool HasParent(const ElementIdentifierType &iId) const
bool DeleteElement(const ElementWrapperType &element)
void UpdateUpTree(const ElementIdentifierType &identifier)
ElementIdentifierType GetRight(const ElementIdentifierType &identifier) const
bool Update(const ElementWrapperType &element)
~PriorityQueueContainer() override=default
void SetElementAtLocation(const ElementIdentifierType &identifier, ElementWrapperType &element)
const ElementWrapperType & Peek() const
ElementIdentifierType GetLeft(const ElementIdentifierType &identifier) const
PriorityQueueContainer(TInputIterator first, TInputIterator last)
const ElementWrapperType & GetElementAtLocation(const ElementIdentifierType &identifier) const
Implements transparent reference counting.
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
SizeValueType IdentifierType
Definition itkIntTypes.h:90