PCL
IndirectArray.h
Go to the documentation of this file.
1 // ____ ______ __
2 // / __ \ / ____// /
3 // / /_/ // / / /
4 // / ____// /___ / /___ PixInsight Class Library
5 // /_/ \____//_____/ PCL 2.6.11
6 // ----------------------------------------------------------------------------
7 // pcl/IndirectArray.h - Released 2024-05-07T15:27:32Z
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_IndirectArray_h
53 #define __PCL_IndirectArray_h
54 
56 
57 #include <pcl/Defs.h>
58 #include <pcl/Diagnostics.h>
59 
60 #include <pcl/Array.h>
61 #include <pcl/Indirect.h>
62 
63 namespace pcl
64 {
65 
66 // ----------------------------------------------------------------------------
67 
90 template <class T, class A = StandardAllocator>
91 class PCL_CLASS IndirectArray : public IndirectContainer<T>
92 {
93 public:
94 
97  using block_allocator = A;
98 
102 
105  using iterator = T**;
106 
109  using const_iterator = T* const*;
110 
114 
118 
122 
126 
130 
134 
138 
139  // -------------------------------------------------------------------------
140 
144  IndirectArray() = default;
145 
150  explicit
152  {
153  m_array.Append( (void*)nullptr, n );
154  }
155 
159  IndirectArray( size_type n, const T* p )
160  {
161  m_array.Append( (void*)p, n );
162  }
163 
168  template <class FI>
169  IndirectArray( FI i, FI j )
170  : m_array( i, j )
171  {
172  }
173 
177  IndirectArray( const IndirectArray& ) = default;
178 
182  IndirectArray( IndirectArray&& ) = default;
183 
192  {
193  }
194 
199  bool IsUnique() const
200  {
201  return m_array.IsUnique();
202  }
203 
211  bool IsAliasOf( const IndirectArray& x ) const
212  {
213  return m_array.IsAliasOf( x.m_array );
214  }
215 
225  {
226  m_array.EnsureUnique();
227  }
228 
233  size_type Size() const
234  {
235  return m_array.Size();
236  }
237 
242  {
243  return m_array.Length();
244  }
245 
252  {
253  return m_array.Capacity();
254  }
255 
264  {
265  return m_array.Available();
266  }
267 
283  bool IsValid() const
284  {
285  return m_array.IsValid();
286  }
287 
291  bool IsEmpty() const
292  {
293  return m_array.IsEmpty();
294  }
295 
301  {
302  return m_array.LowerBound();
303  }
304 
310  {
311  return m_array.UpperBound();
312  }
313 
317  const allocator& Allocator() const
318  {
319  return m_array.Allocator();
320  }
321 
325  void SetAllocator( const allocator& a )
326  {
327  m_array.SetAllocator( a );
328  }
329 
334  {
335  return iterator( m_array.At( i ) );
336  }
337 
342  {
343  return const_iterator( m_array.At( i ) );
344  }
345 
357  {
358  return iterator( m_array.MutableIterator( (const_array_iterator)i ) );
359  }
360 
365  T*& operator []( size_type i )
366  {
367  return (T*&)m_array[i];
368  }
369 
374  const T* operator []( size_type i ) const
375  {
376  return (const T*)m_array[i];
377  }
378 
383  {
384  return (T*&)*Begin();
385  }
386 
391  const T* operator *() const
392  {
393  return (T*)*Begin();
394  }
395 
400  {
401  return iterator( m_array.Begin() );
402  }
403 
408  {
409  return const_iterator( m_array.Begin() );
410  }
411 
416  {
417  return const_iterator( m_array.ConstBegin() );
418  }
419 
424  {
425  return iterator( m_array.End() );
426  }
427 
432  {
433  return const_iterator( m_array.End() );
434  }
435 
440  {
441  return const_iterator( m_array.ConstEnd() );
442  }
443 
451  {
452  return iterator( (array_iterator)m_array.ReverseBegin() );
453  }
454 
462  {
463  return const_iterator( (const_array_iterator)m_array.ReverseBegin() );
464  }
465 
473  {
474  return const_iterator( (const_array_iterator)m_array.ConstReverseBegin() );
475  }
476 
485  {
486  return iterator( (array_iterator)m_array.ReverseEnd() );
487  }
488 
497  {
498  return const_iterator( (const_array_iterator)m_array.ReverseEnd() );
499  }
500 
509  {
510  return const_iterator( (const_array_iterator)m_array.ConstReverseEnd() );
511  }
512 
517  T* First()
518  {
519  return IsEmpty() ? nullptr : *Begin();
520  }
521 
526  const T* First() const
527  {
528  return IsEmpty() ? nullptr : *Begin();
529  }
530 
535  T* Last()
536  {
537  return IsEmpty() ? nullptr : *ReverseBegin();
538  }
539 
544  const T* Last() const
545  {
546  return IsEmpty() ? nullptr : *ReverseBegin();
547  }
548 
558  {
559  m_array.UniquifyIterator( (array_iterator&)i );
560  }
561 
572  {
573  m_array.UniquifyIterators( (array_iterator&)i, (array_iterator&)j );
574  }
575 
576 #ifndef __PCL_NO_STL_COMPATIBLE_ITERATORS
581  {
582  return Begin();
583  }
584 
589  {
590  return Begin();
591  }
592 
597  {
598  return End();
599  }
600 
605  {
606  return End();
607  }
608 #endif // !__PCL_NO_STL_COMPATIBLE_ITERATORS
609 
616  IndirectArray& operator =( const IndirectArray& x )
617  {
618  Assign( x );
619  return *this;
620  }
621 
631  void Assign( const IndirectArray& x )
632  {
633  m_array.Assign( x.m_array );
634  }
635 
639  IndirectArray& operator =( IndirectArray&& x )
640  {
641  Transfer( x );
642  return *this;
643  }
644 
655  {
656  m_array.Transfer( x.m_array );
657  }
658 
669  {
670  m_array.Transfer( x.m_array );
671  }
672 
677  void Assign( const T* p, size_type n = 1 )
678  {
679  m_array.Assign( (void*)p, n );
680  }
681 
688  template <class FI>
689  void Assign( FI i, FI j )
690  {
691  m_array.Assign( i, j );
692  }
693 
705  template <class C>
706  void CloneAssign( const C& x )
707  {
708  PCL_ASSERT_CONTAINER( C, T );
709  CloneObjects( x, (C*)nullptr );
710  }
711 
718  void Import( iterator i, iterator j )
719  {
720  m_array.Import( (array_iterator)i, (array_iterator)j );
721  }
722 
735  {
736  return iterator( m_array.Release() );
737  }
738 
750  {
751  return iterator( m_array.Insert( (array_iterator)const_cast<iterator>( i ), (void*)nullptr, n ) );
752  }
753 
764  {
765  return Grow( ConstEnd(), n );
766  }
767 
780  void Shrink( size_type n = 1 )
781  {
782  if ( n < Length() )
783  Truncate( ConstEnd() - n );
784  else
785  Clear();
786  }
787 
803  void Resize( size_type n )
804  {
805  size_type l = Length();
806  if ( n > l )
807  Expand( n - l );
808  else
809  Shrink( l - n );
810  }
811 
824  {
825  return iterator( m_array.Insert( (array_iterator)const_cast<iterator>( i ), x.m_array ) );
826  }
827 
838  iterator Insert( const_iterator i, const T* p, size_type n = 1 )
839  {
840  return iterator( m_array.Insert( (array_iterator)const_cast<iterator>( i ), (void*)p, n ) );
841  }
842 
855  template <class FI>
856  iterator Insert( const_iterator i, FI p, FI q )
857  {
858  return iterator( m_array.Insert( (array_iterator)const_cast<iterator>( i ), p, q ) );
859  }
860 
865  void Append( const IndirectArray& x )
866  {
867  m_array.Append( x.m_array );
868  }
869 
874  void Append( const T* p, size_type n = 1 )
875  {
876  m_array.Append( (void*)p, n );
877  }
878 
885  template <class FI>
886  void Append( FI p, FI q )
887  {
888  m_array.Append( p, q );
889  }
890 
895  void Prepend( const IndirectArray& x )
896  {
897  m_array.Prepend( x.m_array );
898  }
899 
904  void Prepend( const T* p, size_type n = 1 )
905  {
906  m_array.Prepend( (void*)p, n );
907  }
908 
915  template <class FI>
916  void Prepend( FI p, FI q )
917  {
918  m_array.Prepend( p, q );
919  }
920 
924  void Add( const IndirectArray& x )
925  {
926  Append( x );
927  }
928 
932  void Add( const T* p, size_type n = 1 )
933  {
934  Append( p, n );
935  }
936 
940  template <class FI>
941  void Add( FI i, FI j )
942  {
943  Append( i, j );
944  }
945 
958  void Remove( const_iterator i, size_type n = 1 )
959  {
960  m_array.Remove( (array_iterator)const_cast<iterator>( i ), n );
961  }
962 
976  {
977  m_array.Remove( (array_iterator)const_cast<iterator>( i ),
978  (array_iterator)const_cast<iterator>( j ) );
979  }
980 
995  {
996  m_array.Truncate( (array_iterator)const_cast<iterator>( i ) );
997  }
998 
1006  void Remove( const T& v )
1007  {
1009  for ( const_iterator i = ConstBegin(); i < ConstEnd(); ++i )
1010  if ( *i == nullptr || **i != v )
1011  r.Add( (void*)*i );
1012  if ( r.Length() < m_array.Length() )
1013  m_array.Transfer( r );
1014  }
1015 
1023  template <class BP>
1024  void Remove( const T& v, BP p )
1025  {
1027  for ( const_iterator i = ConstBegin(); i < ConstEnd(); ++i )
1028  if ( *i == nullptr || !p( **i, v ) )
1029  r.Add( (void*)*i );
1030  if ( r.Length() < m_array.Length() )
1031  m_array.Transfer( r );
1032  }
1033 
1040  void Remove( const T* p )
1041  {
1042  m_array.Remove( (void*)p );
1043  }
1044 
1059  void Clear()
1060  {
1061  m_array.Clear();
1062  }
1063 
1076  void Delete( iterator i, size_type n = 1 )
1077  {
1078  Delete( i, i+n );
1079  }
1080 
1099  void Delete( iterator i, iterator j )
1100  {
1101  // NB: Copy-on-write must *not* happen in this function.
1102  if ( i < ConstEnd() )
1103  {
1104  i = pcl::Max( const_cast<iterator>( ConstBegin() ), i );
1105  j = pcl::Min( j, const_cast<iterator>( ConstEnd() ) );
1106  allocator a;
1107  for ( ; i < j; ++i )
1108  if ( *i != nullptr )
1109  DeleteObject( i, a );
1110  }
1111  }
1112 
1124  void Delete( const T& v )
1125  {
1126  // NB: Copy-on-write must *not* happen in this function.
1127  allocator a;
1128  for ( iterator i = const_cast<iterator>( ConstBegin() ); i < ConstEnd(); ++i )
1129  if ( *i != nullptr && **i == v )
1130  DeleteObject( i, a );
1131  }
1132 
1144  template <class BP>
1145  void Delete( const T& v, BP p )
1146  {
1147  // NB: Copy-on-write must *not* happen in this function.
1148  allocator a;
1149  for ( iterator i = const_cast<iterator>( ConstBegin() ); i < ConstEnd(); ++i )
1150  if ( *i != nullptr && p( **i, v ) )
1151  DeleteObject( i, a );
1152  }
1153 
1162  void Delete()
1163  {
1164  // NB: Copy-on-write must *not* happen in this function.
1165  allocator a;
1166  for ( iterator i = const_cast<iterator>( ConstBegin() ); i < ConstEnd(); ++i )
1167  if ( *i != nullptr )
1168  DeleteObject( i, a );
1169  }
1170 
1183  void Destroy( iterator i, size_type n = 1 )
1184  {
1185  Delete( i, n );
1186  Remove( i, n );
1187  }
1188 
1201  {
1202  Delete( i, j );
1203  Remove( i, j );
1204  }
1205 
1217  void Destroy( const T& v )
1218  {
1220  allocator a;
1221  for ( iterator i = const_cast<iterator>( ConstBegin() ); i < ConstEnd(); ++i )
1222  if ( *i != nullptr && **i == v )
1223  DeleteObject( i, a );
1224  else
1225  r.Add( (void*)*i );
1226  // NB: Copy-on-write must *not* happen before this point.
1227  if ( r.Length() < m_array.Length() )
1228  m_array.Transfer( r );
1229  }
1230 
1242  template <class BP>
1243  void Destroy( const T& v, BP p )
1244  {
1246  allocator a;
1247  for ( iterator i = const_cast<iterator>( ConstBegin() ); i < ConstEnd(); ++i )
1248  if ( *i != nullptr && p( **i, v ) )
1249  DeleteObject( i, a );
1250  else
1251  r.Add( (void*)*i );
1252  // NB: Copy-on-write must *not* happen before this point.
1253  if ( r.Length() < m_array.Length() )
1254  m_array.Transfer( r );
1255  }
1256 
1264  void Destroy()
1265  {
1266  Delete();
1267  Clear();
1268  }
1269 
1273  void Pack()
1274  {
1275  m_array.Remove( (void*)nullptr );
1276  }
1277 
1292  {
1293  return iterator( m_array.Replace( (array_iterator)const_cast<iterator>( i ),
1294  (array_iterator)const_cast<iterator>( j ), x.m_array ) );
1295  }
1296 
1311  {
1312  return iterator( m_array.Replace( (array_iterator)const_cast<iterator>( i ),
1313  (array_iterator)const_cast<iterator>( j ), (void*)p, n ) );
1314  }
1315 
1332  template <class FI>
1334  {
1335  return iterator( m_array.Replace( (array_iterator)const_cast<iterator>( i ),
1336  (array_iterator)const_cast<iterator>( j ), p, q ) );
1337  }
1338 
1346  void Reserve( size_type n )
1347  {
1348  m_array.Reserve( n );
1349  }
1350 
1363  void Squeeze()
1364  {
1365  m_array.Squeeze();
1366  }
1367 
1371  void Fill( const T& v )
1372  {
1373  Apply( [v]( T* x ){ *x = v; } );
1374  }
1375 
1380  template <class F>
1381  void Apply( F f )
1382  {
1383  pcl::Apply( Begin(), End(), IndirectUnaryFunction<T*, F>( f ) );
1384  }
1385 
1390  template <class F>
1391  void Apply( F f ) const
1392  {
1393  pcl::Apply( Begin(), End(), IndirectUnaryFunction<const T*, F>( f ) );
1394  }
1395 
1401  template <class F>
1402  iterator FirstThat( F f ) const
1403  {
1404  return const_cast<iterator>( pcl::FirstThat( Begin(), End(), IndirectUnaryPredicate<const T*, F>( f ) ) );
1405  }
1406 
1412  template <class F>
1413  iterator LastThat( F f ) const
1414  {
1415  return const_cast<iterator>( pcl::LastThat( Begin(), End(), IndirectUnaryPredicate<const T*, F>( f ) ) );
1416  }
1417 
1422  size_type Count( const T& v ) const
1423  {
1424  return pcl::Count( Begin(), End(), &v, equal() );
1425  }
1426 
1431  size_type Count( const T* p ) const
1432  {
1433  return m_array.Count( (void*)p );
1434  }
1435 
1441  template <class BP>
1442  size_type Count( const T& v, BP p ) const
1443  {
1444  return pcl::Count( Begin(), End(), &v, IndirectBinaryPredicate<const T*, const T*, BP>( p ) );
1445  }
1446 
1452  template <class UP>
1453  size_type CountIf( UP p ) const
1454  {
1455  return pcl::CountIf( Begin(), End(), IndirectUnaryPredicate<const T*, UP>( p ) );
1456  }
1457 
1461  {
1462  return const_cast<iterator>( pcl::MinItem( Begin(), End(), less() ) );
1463  }
1464 
1467  template <class BP>
1468  iterator MinItem( BP p ) const
1469  {
1470  return const_cast<iterator>( pcl::MinItem( Begin(), End(),
1472  }
1473 
1477  {
1478  return const_cast<iterator>( pcl::MaxItem( Begin(), End(), less() ) );
1479  }
1480 
1483  template <class BP>
1484  iterator MaxItem( BP p ) const
1485  {
1486  return const_cast<iterator>( pcl::MaxItem( Begin(), End(),
1488  }
1489 
1492  void Reverse()
1493  {
1494  m_array.Reverse();
1495  }
1496 
1500  {
1501  m_array.Rotate( n );
1502  }
1503 
1506  void ShiftLeft( const T* p, size_type n = 1 )
1507  {
1508  m_array.ShiftLeft( (void*)p, n );
1509  }
1510 
1513  void ShiftRight( const T* p, size_type n = 1 )
1514  {
1515  m_array.ShiftRight( (void*)p, n );
1516  }
1517 
1520  iterator Search( const T& v ) const
1521  {
1522  return const_cast<iterator>( pcl::LinearSearch( Begin(), End(), &v, equal() ) );
1523  }
1524 
1527  iterator Search( const T* p ) const
1528  {
1529  return iterator( m_array.Search( (void*)p ) );
1530  }
1531 
1534  template <class BP>
1535  iterator Search( const T& v, BP p ) const
1536  {
1537  return const_cast<iterator>( pcl::LinearSearch( Begin(), End(), &v,
1539  }
1540 
1543  iterator SearchLast( const T& v ) const
1544  {
1545  return const_cast<iterator>( pcl::LinearSearchLast( Begin(), End(), &v, equal() ) );
1546  }
1547 
1550  iterator SearchLast( const T* p ) const
1551  {
1552  return iterator( m_array.SearchLast( (void*)p ) );
1553  }
1554 
1557  template <class BP>
1558  iterator SearchLast( const T& v, BP p ) const
1559  {
1560  return const_cast<iterator>( pcl::LinearSearchLast( Begin(), End(), &v,
1562  }
1563 
1566  template <class FI>
1567  iterator SearchSubset( FI i, FI j ) const
1568  {
1569  return const_cast<iterator>( pcl::Search( Begin(), End(), i, j, equal() ) );
1570  }
1571 
1574  template <class FI, class BP>
1575  iterator SearchSubset( FI i, FI j, BP p ) const
1576  {
1577  return const_cast<iterator>( pcl::Search( Begin(), End(), i, j,
1579  }
1580 
1583  template <class C>
1584  iterator SearchSubset( const C& c ) const
1585  {
1586  return const_cast<iterator>( pcl::Search( Begin(), End(), c.Begin(), c.End(), equal() ) );
1587  }
1588 
1591  template <class C, class BP>
1592  iterator SearchSubset( const C& c, BP p ) const
1593  {
1594  return const_cast<iterator>( pcl::Search( Begin(), End(), c.Begin(), c.End(),
1596  }
1597 
1600  template <class BI>
1601  iterator SearchLastSubset( BI i, BI j ) const
1602  {
1603  return const_cast<iterator>( pcl::SearchLast( Begin(), End(), i, j, equal() ) );
1604  }
1605 
1608  template <class BI, class BP>
1609  iterator SearchLastSubset( BI i, BI j, BP p ) const
1610  {
1611  return const_cast<iterator>( pcl::SearchLast( Begin(), End(), i, j,
1613  }
1614 
1617  template <class C>
1618  iterator SearchLastSubset( const C& c ) const
1619  {
1620  return const_cast<iterator>( pcl::SearchLast( Begin(), End(), c.Begin(), c.End(), equal() ) );
1621  }
1622 
1625  template <class C, class BP>
1626  iterator SearchLastSubset( const C& c, BP p ) const
1627  {
1628  return const_cast<iterator>( pcl::SearchLast( Begin(), End(), c.Begin(), c.End(),
1630  }
1631 
1634  bool Contains( const T& v ) const
1635  {
1636  return Search( v ) != End();
1637  }
1638 
1641  bool Contains( const T* p ) const
1642  {
1643  return m_array.Contains( (void*)p );
1644  }
1645 
1648  template <class BP>
1649  bool Contains( const T& v, BP p ) const
1650  {
1651  return Search( v, p ) != End();
1652  }
1653 
1656  template <class FI>
1657  iterator ContainsSubset( FI i, FI j ) const
1658  {
1659  return SearchSubset( i, j ) != End();
1660  }
1661 
1664  template <class FI, class BP>
1665  iterator ContainsSubset( FI i, FI j, BP p ) const
1666  {
1667  return SearchSubset( i, j, p ) != End();
1668  }
1669 
1672  template <class C>
1673  iterator ContainsSubset( const C& c ) const
1674  {
1675  return SearchSubset( c ) != End();
1676  }
1677 
1680  template <class C, class BP>
1681  iterator ContainsSubset( const C& c, BP p ) const
1682  {
1683  return SearchSubset( c, p ) != End();
1684  }
1685 
1688  void Sort()
1689  {
1690  pcl::QuickSort( Begin(), End(), less() );
1691  }
1692 
1695  template <class BP>
1696  void Sort( BP p )
1697  {
1699  }
1700 
1704  friend void Swap( IndirectArray& x1, IndirectArray& x2 )
1705  {
1706  pcl::Swap( x1.m_array, x2.m_array );
1707  }
1708 
1725  template <class S, typename SP>
1726  S& ToSeparated( S& s, SP separator ) const
1727  {
1728  const_iterator i = Begin();
1729  if ( i < End() )
1730  {
1731  while ( *i == nullptr )
1732  if ( ++i == End() )
1733  return s;
1734  s.Append( S( **i ) );
1735  if ( ++i < End() )
1736  do
1737  if ( *i != nullptr )
1738  {
1739  s.Append( separator );
1740  s.Append( S( **i ) );
1741  }
1742  while ( ++i < End() );
1743  }
1744  return s;
1745  }
1746 
1769  template <class S, typename SP, class AF>
1770  S& ToSeparated( S& s, SP separator, AF append ) const
1771  {
1772  const_iterator i = Begin();
1773  if ( i < End() )
1774  {
1775  while ( *i == nullptr )
1776  if ( ++i == End() )
1777  return s;
1778  append( s, S( **i ) );
1779  if ( ++i < End() )
1780  {
1781  S p( separator );
1782  do
1783  if ( *i != nullptr )
1784  {
1785  append( s, p );
1786  append( s, S( **i ) );
1787  }
1788  while ( ++i < End() );
1789  }
1790  }
1791  return s;
1792  }
1793 
1802  template <class S>
1803  S& ToCommaSeparated( S& s ) const
1804  {
1805  return ToSeparated( s, ',' );
1806  }
1807 
1816  template <class S>
1817  S& ToSpaceSeparated( S& s ) const
1818  {
1819  return ToSeparated( s, ' ' );
1820  }
1821 
1830  template <class S>
1831  S& ToTabSeparated( S& s ) const
1832  {
1833  return ToSeparated( s, '\t' );
1834  }
1835 
1844  template <class S>
1845  S& ToNewLineSeparated( S& s ) const
1846  {
1847  return ToSeparated( s, '\n' );
1848  }
1849 
1860  uint64 Hash64( uint64 seed = 0 ) const
1861  {
1862  return m_array.Hash64( seed );
1863  }
1864 
1875  uint32 Hash32( uint32 seed = 0 ) const
1876  {
1877  return m_array.Hash32( seed );
1878  }
1879 
1884  uint64 Hash( uint64 seed = 0 ) const
1885  {
1886  return Hash64( seed );
1887  }
1888 
1889  // -------------------------------------------------------------------------
1890 
1891 private:
1892 
1893  array_implementation m_array;
1894 
1895  void DeleteObject( iterator i, allocator& a )
1896  {
1897  pcl::Destroy( *i );
1898  a.Deallocate( *i );
1899  *i = nullptr;
1900  }
1901 
1902  template <class C>
1903  void CloneObjects( const C& x, DirectContainer<T>* )
1904  {
1905  Clear();
1906  Reserve( x.Length() );
1907  Append( static_cast<T*>( nullptr ), x.Length() );
1908  iterator i = Begin(), j = End();
1909  typename C::const_iterator p = x.Begin(), q = x.End();
1910  for ( allocator a; i < j && p != q; ++i, ++p )
1911  {
1912  *i = a.Allocate( 1 );
1913  pcl::Construct( *i, *p, a );
1914  }
1915  }
1916 
1917  template <class C>
1918  void CloneObjects( const C& x, IndirectContainer<T>* )
1919  {
1920  Clear();
1921  Reserve( x.Length() );
1922  Append( static_cast<T*>( nullptr ), x.Length() );
1923  iterator i = Begin(), j = End();
1924  typename C::const_iterator p = x.Begin(), q = x.End();
1925  for ( allocator a; i < j && p != q; ++i, ++p )
1926  if ( *p != nullptr )
1927  {
1928  *i = a.Allocate( 1 );
1929  pcl::Construct( *i, **p, a );
1930  }
1931  }
1932 };
1933 
1934 // ----------------------------------------------------------------------------
1935 
1942 template <class T, class A> inline
1944 {
1945  return x1.Length() == x2.Length() && pcl::Equal( x1.Begin(), x2.Begin(), x2.End(), IndirectArray<T,A>::equal() );
1946 }
1947 
1954 template <class T, class A> inline
1956 {
1957  return pcl::Compare( x1.Begin(), x1.End(), x2.Begin(), x2.End(), IndirectArray<T,A>::less() ) < 0;
1958 }
1959 
1967 template <class T, class A, class V> inline
1968 IndirectArray<T,A>& operator <<( IndirectArray<T,A>& x, const V* p )
1969 {
1970  x.Append( static_cast<const T*>( p ) );
1971  return x;
1972 }
1973 
1981 template <class T, class A, class V> inline
1982 IndirectArray<T,A>& operator <<( IndirectArray<T,A>&& x, const V* p )
1983 {
1984  x.Append( static_cast<const T*>( p ) );
1985  return x;
1986 }
1987 
1993 template <class T, class A> inline
1994 IndirectArray<T,A>& operator <<( IndirectArray<T,A>& x1, const IndirectArray<T,A>& x2 )
1995 {
1996  x1.Append( x2 );
1997  return x1;
1998 }
1999 
2005 template <class T, class A> inline
2006 IndirectArray<T,A>& operator <<( IndirectArray<T,A>&& x1, const IndirectArray<T,A>& x2 )
2007 {
2008  x1.Append( x2 );
2009  return x1;
2010 }
2011 
2012 // ----------------------------------------------------------------------------
2013 
2014 } // pcl
2015 
2016 #endif // __PCL_IndirectArray_h
2017 
2018 // ----------------------------------------------------------------------------
2019 // EOF pcl/IndirectArray.h - Released 2024-05-07T15:27:32Z
Provides memory allocation for PCL containers.
Definition: Allocator.h:132
Allocator()=default
Generic dynamic array.
Definition: Array.h:100
size_type Length() const noexcept
Definition: Array.h:266
void Add(const Array &x)
Definition: Array.h:1007
T * iterator
Definition: Array.h:113
const T * const_iterator
Definition: Array.h:117
Generic dynamic array of pointers to objects.
Definition: IndirectArray.h:92
void Assign(FI i, FI j)
void Destroy(iterator i, size_type n=1)
size_type UpperBound() const
void Assign(const T *p, size_type n=1)
iterator SearchSubset(FI i, FI j, BP p) const
size_type Length() const
void Transfer(IndirectArray &x)
reverse_iterator ReverseEnd()
iterator MinItem(BP p) const
bool IsValid() const
void Append(FI p, FI q)
void Add(const IndirectArray &x)
void Truncate(const_iterator i)
void Remove(const T &v)
T *const * const_iterator
IndirectArray(size_type n, const T *p)
size_type Size() const
const_iterator ConstBegin() const
iterator SearchLastSubset(BI i, BI j, BP p) const
void Delete(const T &v, BP p)
IndirectArray(FI i, FI j)
iterator MaxItem() const
iterator LastThat(F f) const
bool IsEmpty() const
iterator Replace(const_iterator i, const_iterator j, FI p, FI q)
IndirectArray()=default
void UniquifyIterators(iterator &i, iterator &j)
void Reserve(size_type n)
const allocator & Allocator() const
iterator ContainsSubset(FI i, FI j) const
friend void Swap(IndirectArray &x1, IndirectArray &x2)
bool Contains(const T &v, BP p) const
IndirectArray(IndirectArray &&)=default
typename array_implementation::const_iterator const_array_iterator
const_iterator ConstEnd() const
size_type Available() const
iterator Expand(size_type n=1)
void Remove(const T &v, BP p)
iterator SearchSubset(const C &c, BP p) const
void Remove(const T *p)
uint32 Hash32(uint32 seed=0) const
iterator ContainsSubset(const C &c) const
void Remove(const_iterator i, const_iterator j)
void Destroy(const T &v, BP p)
iterator Search(const T *p) const
iterator SearchSubset(const C &c) const
void ShiftRight(const T *p, size_type n=1)
void UniquifyIterator(iterator &i)
iterator Insert(const_iterator i, FI p, FI q)
void SetAllocator(const allocator &a)
const_reverse_iterator ReverseBegin() const
bool Contains(const T *p) const
iterator Search(const T &v) const
iterator SearchLastSubset(BI i, BI j) const
size_type Count(const T &v, BP p) const
reverse_iterator ReverseBegin()
iterator SearchLast(const T &v, BP p) const
void Fill(const T &v)
void Destroy(iterator i, iterator j)
const_iterator At(size_type i) const
void Prepend(FI p, FI q)
void Delete(iterator i, size_type n=1)
iterator Grow(const_iterator i, size_type n=1)
uint64 Hash64(uint64 seed=0) const
size_type CountIf(UP p) const
size_type Capacity() const
const_reverse_iterator ConstReverseBegin() const
iterator At(size_type i)
void Add(FI i, FI j)
void Rotate(distance_type n)
void Assign(const IndirectArray &x)
iterator FirstThat(F f) const
bool IsAliasOf(const IndirectArray &x) const
bool Contains(const T &v) const
void Resize(size_type n)
void Transfer(IndirectArray &&x)
const_reverse_iterator ReverseEnd() const
iterator Replace(const_iterator i, const_iterator j, const IndirectArray &x)
void Append(const T *p, size_type n=1)
size_type LowerBound() const
void Add(const T *p, size_type n=1)
IndirectArray(const IndirectArray &)=default
void Prepend(const IndirectArray &x)
void Import(iterator i, iterator j)
iterator Search(const T &v, BP p) const
void Apply(F f) const
void ShiftLeft(const T *p, size_type n=1)
iterator MinItem() const
void Delete(const T &v)
const_iterator begin() const
iterator ContainsSubset(const C &c, BP p) const
iterator Insert(const_iterator i, const T *p, size_type n=1)
const_iterator end() const
uint64 Hash(uint64 seed=0) const
void Remove(const_iterator i, size_type n=1)
iterator SearchLast(const T &v) const
iterator ContainsSubset(FI i, FI j, BP p) const
IndirectArray(size_type n)
iterator Insert(const_iterator i, const IndirectArray &x)
void Shrink(size_type n=1)
const_iterator Begin() const
const_iterator End() const
typename array_implementation::iterator array_iterator
void Append(const IndirectArray &x)
size_type Count(const T &v) const
iterator SearchLastSubset(const C &c, BP p) const
iterator SearchLastSubset(const C &c) const
bool IsUnique() const
iterator SearchLast(const T *p) const
iterator MaxItem(BP p) const
void Prepend(const T *p, size_type n=1)
iterator MutableIterator(const_iterator i)
iterator Replace(const_iterator i, const_iterator j, const T *p, size_type n=1)
void CloneAssign(const C &x)
const_reverse_iterator ConstReverseEnd() const
void Destroy(const T &v)
size_type Count(const T *p) const
iterator SearchSubset(FI i, FI j) const
void Delete(iterator i, iterator j)
A wrapper class that applies a binary predicate to pointers to objects.
Definition: Indirect.h:236
Root base class of all PCL containers of pointers to objects.
Definition: Container.h:90
A wrapper class that applies a unary function to pointers to objects.
Definition: Indirect.h:80
A wrapper class that applies a unary predicate to pointers to objects.
Definition: Indirect.h:185
Reverse random access iterator.
Definition: Iterator.h:420
Array< T, A > & operator<<(Array< T, A > &x, const V &v)
Definition: Array.h:2118
bool operator==(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2090
bool operator<(const Array< T, A > &x1, const Array< T, A > &x2) noexcept
Definition: Array.h:2101
Complex< T1 > operator*(const Complex< T1 > &c1, const Complex< T2 > &c2) noexcept
Definition: Complex.h:548
uint64 Hash64(const void *data, size_type size, uint64 seed=0) noexcept
Definition: Math.h:4750
void Construct(T *p, A &a)
Definition: Allocator.h:247
void Destroy(T *p)
Definition: Allocator.h:277
void Swap(GenericPoint< T > &p1, GenericPoint< T > &p2) noexcept
Definition: Point.h:1459
unsigned long long uint64
Definition: Defs.h:682
unsigned int uint32
Definition: Defs.h:666
FI LinearSearch(FI i, FI j, const T &v) noexcept
Definition: Search.h:91
BI1 SearchLast(BI1 i1, BI1 j1, FI2 i2, FI2 j2) noexcept
Definition: Search.h:449
BI LinearSearchLast(BI i, BI j, const T &v) noexcept
Definition: Search.h:129
FI1 Search(FI1 i1, FI1 j1, FI2 i2, FI2 j2) noexcept
Definition: Search.h:397
ptrdiff_t distance_type
Definition: Defs.h:615
size_t size_type
Definition: Defs.h:609
void QuickSort(RI i, RI j)
Definition: Sort.h:236
size_type CountIf(FI i, FI j, UP p) noexcept(noexcept(p))
Definition: Utility.h:423
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
bool Equal(FI1 i1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:592
int Compare(FI1 i1, FI1 j1, FI2 i2, FI2 j2) noexcept
Definition: Utility.h:639
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
A functional class that tests two pointers for equality of the pointed objects.
Definition: Indirect.h:278
A functional class that applies the less than relational operator to the objects pointed to by two po...
Definition: Indirect.h:300