PCL
Utility.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.7.0
6 // ----------------------------------------------------------------------------
7 // pcl/Utility.h - Released 2024-06-18T15:48:54Z
8 // ----------------------------------------------------------------------------
9 // This file is part of the PixInsight Class Library (PCL).
10 // PCL is a multiplatform C++ framework for development of PixInsight modules.
11 //
12 // Copyright (c) 2003-2024 Pleiades Astrophoto S.L. All Rights Reserved.
13 //
14 // Redistribution and use in both source and binary forms, with or without
15 // modification, is permitted provided that the following conditions are met:
16 //
17 // 1. All redistributions of source code must retain the above copyright
18 // notice, this list of conditions and the following disclaimer.
19 //
20 // 2. All redistributions in binary form must reproduce the above copyright
21 // notice, this list of conditions and the following disclaimer in the
22 // documentation and/or other materials provided with the distribution.
23 //
24 // 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
25 // of their contributors, may be used to endorse or promote products derived
26 // from this software without specific prior written permission. For written
27 // permission, please contact info@pixinsight.com.
28 //
29 // 4. All products derived from this software, in any form whatsoever, must
30 // reproduce the following acknowledgment in the end-user documentation
31 // and/or other materials provided with the product:
32 //
33 // "This product is based on software from the PixInsight project, developed
34 // by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
35 //
36 // Alternatively, if that is where third-party acknowledgments normally
37 // appear, this acknowledgment must be reproduced in the product itself.
38 //
39 // THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
40 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
41 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
43 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
44 // EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
45 // INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
46 // DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
49 // POSSIBILITY OF SUCH DAMAGE.
50 // ----------------------------------------------------------------------------
51 
52 #ifndef __PCL_Utility_h
53 #define __PCL_Utility_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/Association.h>
61 
62 namespace pcl
63 {
64 
65 // ----------------------------------------------------------------------------
66 
81 // ----------------------------------------------------------------------------
82 
89 template <typename T> inline constexpr
90 const T& Min( const T& a, const T& b ) noexcept
91 {
92  return (b < a) ? b : a;
93 }
94 
95 // ----------------------------------------------------------------------------
96 
104 template <typename T, class BP> inline
105 const T& Min( const T& a, const T& b, BP p ) noexcept( noexcept( p ) )
106 {
107  return p( b, a ) ? b : a;
108 }
109 
110 // ----------------------------------------------------------------------------
111 
118 template <typename T> inline constexpr
119 const T& Max( const T& a, const T& b ) noexcept
120 {
121  return (a < b) ? b : a;
122 }
123 
124 // ----------------------------------------------------------------------------
125 
133 template <typename T, class BP> inline
134 const T& Max( const T& a, const T& b, BP p ) noexcept( noexcept( p ) )
135 {
136  return p( a, b ) ? b : a;
137 }
138 
139 // ----------------------------------------------------------------------------
140 
150 template <typename T> inline constexpr
151 const T& Median( const T& a, const T& b, const T& c ) noexcept
152 {
153  return (a < b) ? ((b < c) ? b : ((a < c) ? c : a)) :
154  ((a < c) ? a : ((b < c) ? c : b));
155 }
156 
157 // ----------------------------------------------------------------------------
158 
169 template <typename T, class BP> inline
170 const T& Median( const T& a, const T& b, const T& c, BP p ) noexcept( noexcept( p ) )
171 {
172  return p( a, b ) ? (p( b, c ) ? b : (p( a, c ) ? c : a)) :
173  (p( a, c ) ? a : (p( b, c ) ? c : b));
174 }
175 
176 // ----------------------------------------------------------------------------
177 
189 template <typename T> inline constexpr
190 const T& Range( const T& x, const T& a, const T& b ) noexcept
191 {
192  PCL_PRECONDITION( a < b )
193  return (x < a) ? a : ((b < x) ? b : x);
194 }
195 
196 // ----------------------------------------------------------------------------
197 
209 template <typename T, class BP> inline
210 const T& Range( const T& x, const T& a, const T& b, BP p ) noexcept( noexcept( p ) )
211 {
212  PCL_PRECONDITION( p( a, b ) )
213  return p( x, a ) ? a : (p( b, x ) ? b : x);
214 }
215 
216 // ----------------------------------------------------------------------------
217 
223 #define ItemsInArray( a ) (sizeof( a )/sizeof( *a ))
224 
225 // ----------------------------------------------------------------------------
226 
232 template <typename T> inline
233 void Swap( T& a, T& b ) noexcept( std::is_nothrow_copy_constructible<T>::value
234  && std::is_nothrow_copy_assignable<T>::value
235  && std::is_nothrow_move_assignable<T>::value )
236 {
237  T c( a ); a = b; b = std::move( c );
238 }
239 
240 // ----------------------------------------------------------------------------
241 
248 template <class FI, class F> inline
249 void Apply( FI i, FI j, F f ) noexcept( noexcept( f ) )
250 {
251  for( ; i != j; ++i )
252  f( *i );
253 }
254 
255 // ----------------------------------------------------------------------------
256 
264 template <class FI, class F, typename T1> inline
265 void Apply( FI i, FI j, F f, T1 x ) noexcept( noexcept( f ) )
266 {
267  for( ; i != j; ++i )
268  f( *i, x );
269 }
270 
271 // ----------------------------------------------------------------------------
272 
281 template <class FI, class F, class UP> inline
282 void ApplyIf( FI i, FI j, F f, UP p ) noexcept( noexcept( f ) && noexcept( p ) )
283 {
284  for( ; i != j; ++i )
285  if ( p( *i ) )
286  f( *i );
287 }
288 
289 // ----------------------------------------------------------------------------
290 
299 template <class FI, class F, class UP, typename T1> inline
300 void ApplyIf( FI i, FI j, F f, UP p, T1 x ) noexcept( noexcept( f ) && noexcept( p ) )
301 {
302  for( ; i != j; ++i )
303  if ( p( *i ) )
304  f( *i, x );
305 }
306 
307 // ----------------------------------------------------------------------------
308 
315 template <class FI, class UP> inline
316 FI FirstThat( FI i, FI j, UP p ) noexcept( noexcept( p ) )
317 {
318  for ( ; i != j; ++i )
319  if ( p( *i ) )
320  break;
321  return i;
322 }
323 
324 // ----------------------------------------------------------------------------
325 
332 template <class FI, class UP, typename T1> inline
333 FI FirstThat( FI i, FI j, UP p, T1 x ) noexcept( noexcept( p ) )
334 {
335  for ( ; i != j; ++i )
336  if ( p( *i, x ) )
337  break;
338  return i;
339 }
340 
341 // ----------------------------------------------------------------------------
342 
349 template <class BI, class UP> inline
350 BI LastThat( BI i, BI j, UP p ) noexcept( noexcept( p ) )
351 {
352  for ( BI k = j; i != k; )
353  if ( p( *--k ) )
354  return k;
355  return j;
356 }
357 
358 // ----------------------------------------------------------------------------
359 
366 template <class BI, class UP, typename T1> inline
367 BI LastThat( BI i, BI j, UP p, T1 x ) noexcept( noexcept( p ) )
368 {
369  for ( BI k = j; i != k; )
370  if ( p( *--k, x ) )
371  return k;
372  return j;
373 }
374 
375 // ----------------------------------------------------------------------------
376 
383 template <class FI, typename T> inline
384 size_type Count( FI i, FI j, const T& v ) noexcept
385 {
386  size_type N = 0;
387  for( ; i != j; ++i )
388  if ( *i == v )
389  ++N;
390  return N;
391 }
392 
393 // ----------------------------------------------------------------------------
394 
403 template <class FI, typename T, class BP> inline
404 size_type Count( FI i, FI j, const T& v, BP p ) noexcept( noexcept( p ) )
405 {
406  size_type N = 0;
407  for( ; i != j; ++i )
408  if ( p( *i, v ) )
409  ++N;
410  return N;
411 }
412 
413 // ----------------------------------------------------------------------------
414 
422 template <class FI, class UP> inline
423 size_type CountIf( FI i, FI j, UP p ) noexcept( noexcept( p ) )
424 {
425  size_type N = 0;
426  for( ; i != j; ++i )
427  if ( p( *i ) )
428  ++N;
429  return N;
430 }
431 
432 // ----------------------------------------------------------------------------
433 
440 template <class FI> inline
441 FI MinItem( FI i, FI j ) noexcept
442 {
443  FI k = i;
444  if ( i != j )
445  while ( ++i != j )
446  if ( *i < *k )
447  k = i;
448  return k;
449 }
450 
451 // ----------------------------------------------------------------------------
452 
459 template <class FI, class BP> inline
460 FI MinItem( FI i, FI j, BP p ) noexcept( noexcept( p ) )
461 {
462  FI k = i;
463  if ( i != j )
464  while ( ++i != j )
465  if ( p( *i, *k ) )
466  k = i;
467  return k;
468 }
469 
470 // ----------------------------------------------------------------------------
471 
478 template <class FI> inline
479 FI MaxItem( FI i, FI j ) noexcept
480 {
481  FI k = i;
482  if ( i != j )
483  while ( ++i != j )
484  if ( *k < *i )
485  k = i;
486  return k;
487 }
488 
489 // ----------------------------------------------------------------------------
490 
497 template <class FI, class BP> inline
498 FI MaxItem( FI i, FI j, BP p ) noexcept( noexcept( p ) )
499 {
500  FI k = i;
501  if ( i != j )
502  while ( ++i != j )
503  if ( p( *k, *i ) )
504  k = i;
505  return k;
506 }
507 
508 // ----------------------------------------------------------------------------
509 
516 template <class FI> inline
517 void FindExtremeItems( FI& kmin, FI& kmax, FI i, FI j ) noexcept
518 {
519  kmin = kmax = i;
520  if ( i != j )
521  while ( ++i != j )
522  {
523  if ( *i < *kmin )
524  kmin = i;
525  if ( *kmax < *i )
526  kmax = i;
527  }
528 }
529 
530 // ----------------------------------------------------------------------------
531 
538 template <class FI, class BP> inline
539 void FindExtremeItems( FI& kmin, FI& kmax, FI i, FI j, BP p ) noexcept( noexcept( p ) )
540 {
541  kmin = kmax = i;
542  if ( i != j )
543  while ( ++i != j )
544  {
545  if ( p( *i, *kmin ) )
546  kmin = i;
547  if ( p( *kmax, *i ) )
548  kmax = i;
549  }
550 }
551 
552 // ----------------------------------------------------------------------------
553 
560 template <class FI1, class FI2> inline
561 Association<FI1, FI2> FindNotEqual( FI1 i1, FI2 i2, FI2 j2 ) noexcept
562 {
563  for ( ; i2 != j2 && *i1 == *i2; ++i1, ++i2 ) {}
564  return Associate( i1, i2 );
565 }
566 
567 // ----------------------------------------------------------------------------
568 
575 template <class FI1, class FI2, class BP> inline
576 Association<FI1, FI2> FindNotEqual( FI1 i1, FI2 i2, FI2 j2, BP p ) noexcept
577 {
578  for ( ; i2 != j2 && p( *i1, *i2 ); ++i1, ++i2 ) {}
579  return Associate( i1, i2 );
580 }
581 
582 // ----------------------------------------------------------------------------
583 
591 template <class FI1, class FI2> inline
592 bool Equal( FI1 i1, FI2 i2, FI2 j2 ) noexcept
593 {
594  return FindNotEqual( i1, i2, j2 ).second == j2;
595 }
596 
597 // ----------------------------------------------------------------------------
598 
606 template <class FI1, class FI2, class BP> inline
607 bool Equal( FI1 i1, FI2 i2, FI2 j2, BP p ) noexcept( noexcept( p ) )
608 {
609  return FindNotEqual( i1, i2, j2, p ).second == j2;
610 }
611 
612 // ----------------------------------------------------------------------------
613 
638 template <class FI1, class FI2> inline
639 int Compare( FI1 i1, FI1 j1, FI2 i2, FI2 j2 ) noexcept
640 {
641  for ( ; ; ++i1, ++i2 )
642  {
643  if ( i1 == j1 )
644  return (i2 == j2) ? 0 : -1;
645  if ( i2 == j2 )
646  return +1;
647  if ( *i1 < *i2 )
648  return -1;
649  if ( *i2 < *i1 )
650  return +1;
651  }
652 }
653 
654 // ----------------------------------------------------------------------------
655 
682 template <class FI1, class FI2, class BP> inline
683 int Compare( FI1 i1, FI1 j1, FI2 i2, FI2 j2, BP p ) noexcept( noexcept( p ) )
684 {
685  for ( ; ; ++i1, ++i2 )
686  {
687  if ( i1 == j1 )
688  return (i2 == j2) ? 0 : -1;
689  if ( i2 == j2 )
690  return +1;
691  if ( p( *i1, *i2 ) )
692  return -1;
693  if ( p( *i2, *i1 ) )
694  return +1;
695  }
696 }
697 
698 // ----------------------------------------------------------------------------
699 
700 } // pcl
701 
702 #endif // __PCL_Utility_h
703 
704 // ----------------------------------------------------------------------------
705 // EOF pcl/Utility.h - Released 2024-06-18T15:48:54Z
Generic association of two objects.
Definition: Association.h:72
Association< T1, T2 > Associate(const T1 &x1, const T2 &x2)
Definition: Association.h:116
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2) noexcept
Definition: Point.h:1459
size_t size_type
Definition: Defs.h:609
double Median(const T *__restrict__ i, const T *__restrict__ j)
Definition: Math.h:2878
size_type CountIf(FI i, FI j, UP p) noexcept(noexcept(p))
Definition: Utility.h:423
void ApplyIf(FI i, FI j, F f, UP p) noexcept(noexcept(f) &&noexcept(p))
Definition: Utility.h:282
constexpr const T & Min(const T &a, const T &b) noexcept
Definition: Utility.h:90
BI LastThat(BI i, BI j, UP p) noexcept(noexcept(p))
Definition: Utility.h:350
size_type Count(FI i, FI j, const T &v) noexcept
Definition: Utility.h:384
FI MinItem(FI i, FI j) noexcept
Definition: Utility.h:441
Association< FI1, FI2 > FindNotEqual(FI1 i1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:561
bool Equal(FI1 i1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:592
void FindExtremeItems(FI &kmin, FI &kmax, FI i, FI j) noexcept
Definition: Utility.h:517
int Compare(FI1 i1, FI1 j1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:639
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
Definition: Utility.h:190
constexpr const T & Max(const T &a, const T &b) noexcept
Definition: Utility.h:119
FI MaxItem(FI i, FI j) noexcept
Definition: Utility.h:479
void Apply(FI i, FI j, F f) noexcept(noexcept(f))
Definition: Utility.h:249
FI FirstThat(FI i, FI j, UP p) noexcept(noexcept(p))
Definition: Utility.h:316
PCL root namespace.
Definition: AbstractImage.h:77