Skip to content

Commit b1958fa

Browse files
authored
Merge pull request OSGeo#13069 from rouault/GDALDataset_const
GDALDataset const related changes
2 parents 1e5474b + fd77963 commit b1958fa

File tree

3 files changed

+249
-12
lines changed

3 files changed

+249
-12
lines changed

autotest/cpp/test_gdal.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,26 @@ TEST_F(test_gdal, GDALDataset_GetBands)
12991299
EXPECT_EQ(poDS->GetBands()[static_cast<size_t>(0)], poDS->GetRasterBand(1));
13001300
}
13011301

1302+
// Test GDALDataset::GetBands()
1303+
TEST_F(test_gdal, GDALDataset_GetBands_const)
1304+
{
1305+
GDALDatasetUniquePtr poDS(
1306+
MEMDataset::Create("", 1, 1, 3, GDT_Byte, nullptr));
1307+
const GDALDataset *poConstDS = poDS.get();
1308+
int nExpectedNumber = 1;
1309+
for (const auto *poBand : poConstDS->GetBands())
1310+
{
1311+
EXPECT_EQ(poBand->GetBand(), nExpectedNumber);
1312+
nExpectedNumber++;
1313+
}
1314+
ASSERT_EQ(nExpectedNumber, 3 + 1);
1315+
1316+
ASSERT_EQ(poConstDS->GetBands().size(), 3U);
1317+
EXPECT_EQ(poConstDS->GetBands()[0], poConstDS->GetRasterBand(1));
1318+
EXPECT_EQ(poConstDS->GetBands()[static_cast<size_t>(0)],
1319+
poConstDS->GetRasterBand(1));
1320+
}
1321+
13021322
TEST_F(test_gdal, GDALExtendedDataType)
13031323
{
13041324
#ifndef __COVERITY__

gcore/gdal_priv.h

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,45 @@ class CPL_DLL GDALDataset : public GDALMajorObject
918918

919919
Bands GetBands();
920920

921+
/** Class returned by GetBands() that act as a container for raster bands.
922+
*/
923+
class CPL_DLL ConstBands
924+
{
925+
private:
926+
friend class GDALDataset;
927+
const GDALDataset *const m_poSelf;
928+
929+
CPL_INTERNAL explicit ConstBands(const GDALDataset *poSelf)
930+
: m_poSelf(poSelf)
931+
{
932+
}
933+
934+
class CPL_DLL Iterator
935+
{
936+
struct Private;
937+
std::unique_ptr<Private> m_poPrivate;
938+
939+
public:
940+
Iterator(const GDALDataset *poDS, bool bStart);
941+
~Iterator();
942+
const GDALRasterBand *operator*() const;
943+
Iterator &operator++();
944+
bool operator!=(const Iterator &it) const;
945+
};
946+
947+
public:
948+
const Iterator begin() const;
949+
950+
const Iterator end() const;
951+
952+
size_t size() const;
953+
954+
const GDALRasterBand *operator[](int iBand) const;
955+
const GDALRasterBand *operator[](size_t iBand) const;
956+
};
957+
958+
ConstBands GetBands() const;
959+
921960
virtual CPLErr FlushCache(bool bAtClosing = false);
922961
virtual CPLErr DropCache();
923962

@@ -964,7 +1003,7 @@ class CPL_DLL GDALDataset : public GDALMajorObject
9641003
virtual GDALDriver *GetDriver(void);
9651004
virtual char **GetFileList(void);
9661005

967-
virtual const char *GetDriverName();
1006+
const char *GetDriverName() const;
9681007

9691008
virtual const OGRSpatialReference *GetGCPSpatialRef() const;
9701009
virtual int GetGCPCount();
@@ -973,7 +1012,7 @@ class CPL_DLL GDALDataset : public GDALMajorObject
9731012
const OGRSpatialReference *poGCP_SRS);
9741013

9751014
// Compatibility layer
976-
const char *GetGCPProjection();
1015+
const char *GetGCPProjection() const;
9771016
CPLErr SetGCPs(int nGCPCount, const GDAL_GCP *pasGCPList,
9781017
const char *pszGCPProjection);
9791018

@@ -2005,6 +2044,13 @@ class CPL_DLL GDALRasterBand : public GDALMajorObject
20052044
//! @endcond
20062045

20072046
protected:
2047+
GDALRasterBand();
2048+
explicit GDALRasterBand(int bForceCachedIO);
2049+
2050+
//! @cond Doxygen_Suppress
2051+
GDALRasterBand(GDALRasterBand &&) = default;
2052+
//! @endcond
2053+
20082054
virtual CPLErr IReadBlock(int nBlockXOff, int nBlockYOff, void *pData) = 0;
20092055
virtual CPLErr IWriteBlock(int nBlockXOff, int nBlockYOff, void *pData);
20102056

@@ -2059,13 +2105,6 @@ class CPL_DLL GDALRasterBand : public GDALMajorObject
20592105
//! @endcond
20602106

20612107
public:
2062-
GDALRasterBand();
2063-
explicit GDALRasterBand(int bForceCachedIO);
2064-
2065-
//! @cond Doxygen_Suppress
2066-
GDALRasterBand(GDALRasterBand &&) = default;
2067-
//! @endcond
2068-
20692108
~GDALRasterBand() override;
20702109

20712110
int GetXSize() const;

gcore/gdaldataset.cpp

Lines changed: 181 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,7 @@ int CPL_STDCALL GDALGetGCPCount(GDALDatasetH hDS)
20172017
* It should not be altered, freed or expected to last for long.
20182018
*/
20192019

2020-
const char *GDALDataset::GetGCPProjection()
2020+
const char *GDALDataset::GetGCPProjection() const
20212021
{
20222022
const auto poSRS = GetGCPSpatialRef();
20232023
if (!poSRS || !m_poPrivate)
@@ -5076,7 +5076,7 @@ char **GDALDataset::GetMetadataDomainList()
50765076
/** Return driver name.
50775077
* @return driver name.
50785078
*/
5079-
const char *GDALDataset::GetDriverName()
5079+
const char *GDALDataset::GetDriverName() const
50805080
{
50815081
if (poDriver)
50825082
return poDriver->GetDescription();
@@ -9491,7 +9491,7 @@ bool GDALDataset::Bands::Iterator::operator!=(const Iterator &it) const
94919491
}
94929492

94939493
/************************************************************************/
9494-
/* GetBands() */
9494+
/* GetBands() */
94959495
/************************************************************************/
94969496

94979497
/** Function that returns an iterable object over GDALRasterBand in the dataset.
@@ -9611,6 +9611,184 @@ GDALRasterBand *GDALDataset::Bands::operator[](size_t iBand)
96119611
return m_poSelf->GetRasterBand(1 + static_cast<int>(iBand));
96129612
}
96139613

9614+
/************************************************************************/
9615+
/* GDALDataset::ConstBands::Iterator::Private */
9616+
/************************************************************************/
9617+
9618+
struct GDALDataset::ConstBands::Iterator::Private
9619+
{
9620+
const GDALRasterBand *m_poBand = nullptr;
9621+
int m_iCurBand = 0;
9622+
int m_nBandCount = 0;
9623+
const GDALDataset *m_poDS = nullptr;
9624+
};
9625+
9626+
GDALDataset::ConstBands::Iterator::Iterator(const GDALDataset *poDS,
9627+
bool bStart)
9628+
: m_poPrivate(new GDALDataset::ConstBands::Iterator::Private())
9629+
{
9630+
m_poPrivate->m_poDS = poDS;
9631+
m_poPrivate->m_nBandCount = poDS->GetRasterCount();
9632+
if (bStart)
9633+
{
9634+
if (m_poPrivate->m_nBandCount)
9635+
m_poPrivate->m_poBand = poDS->GetRasterBand(1);
9636+
}
9637+
else
9638+
{
9639+
m_poPrivate->m_iCurBand = m_poPrivate->m_nBandCount;
9640+
}
9641+
}
9642+
9643+
GDALDataset::ConstBands::Iterator::~Iterator() = default;
9644+
9645+
const GDALRasterBand *GDALDataset::ConstBands::Iterator::operator*() const
9646+
{
9647+
return m_poPrivate->m_poBand;
9648+
}
9649+
9650+
GDALDataset::ConstBands::Iterator &
9651+
GDALDataset::ConstBands::Iterator::operator++()
9652+
{
9653+
m_poPrivate->m_iCurBand++;
9654+
if (m_poPrivate->m_iCurBand < m_poPrivate->m_nBandCount)
9655+
{
9656+
m_poPrivate->m_poBand =
9657+
m_poPrivate->m_poDS->GetRasterBand(1 + m_poPrivate->m_iCurBand);
9658+
}
9659+
else
9660+
{
9661+
m_poPrivate->m_poBand = nullptr;
9662+
}
9663+
return *this;
9664+
}
9665+
9666+
bool GDALDataset::ConstBands::Iterator::operator!=(const Iterator &it) const
9667+
{
9668+
return m_poPrivate->m_iCurBand != it.m_poPrivate->m_iCurBand;
9669+
}
9670+
9671+
/************************************************************************/
9672+
/* GetBands() */
9673+
/************************************************************************/
9674+
9675+
/** Function that returns an iterable object over GDALRasterBand in the dataset.
9676+
*
9677+
* This is a C++ iterator friendly version of GetRasterBand().
9678+
*
9679+
* Typical use is:
9680+
* \code{.cpp}
9681+
* for( const auto* poBand: poDS->GetConstBands() )
9682+
* {
9683+
* std::cout << "Band << poBand->GetDescription() << std::endl;
9684+
* }
9685+
* \endcode
9686+
*
9687+
* @see GetRasterBand()
9688+
*
9689+
* @since GDAL 3.12
9690+
*/
9691+
GDALDataset::ConstBands GDALDataset::GetBands() const
9692+
{
9693+
return ConstBands(this);
9694+
}
9695+
9696+
/************************************************************************/
9697+
/* begin() */
9698+
/************************************************************************/
9699+
9700+
/**
9701+
\brief Return beginning of band iterator.
9702+
9703+
@since GDAL 3.12
9704+
*/
9705+
9706+
const GDALDataset::ConstBands::Iterator GDALDataset::ConstBands::begin() const
9707+
{
9708+
return {m_poSelf, true};
9709+
}
9710+
9711+
/************************************************************************/
9712+
/* end() */
9713+
/************************************************************************/
9714+
9715+
/**
9716+
\brief Return end of band iterator.
9717+
9718+
@since GDAL 3.12
9719+
*/
9720+
9721+
const GDALDataset::ConstBands::Iterator GDALDataset::ConstBands::end() const
9722+
{
9723+
return {m_poSelf, false};
9724+
}
9725+
9726+
/************************************************************************/
9727+
/* size() */
9728+
/************************************************************************/
9729+
9730+
/**
9731+
\brief Get the number of raster bands in this dataset.
9732+
9733+
@return raster band count.
9734+
9735+
@since GDAL 3.12
9736+
*/
9737+
9738+
size_t GDALDataset::ConstBands::size() const
9739+
{
9740+
return static_cast<size_t>(m_poSelf->GetRasterCount());
9741+
}
9742+
9743+
/************************************************************************/
9744+
/* operator[]() */
9745+
/************************************************************************/
9746+
/**
9747+
\brief Fetch a raster band by index.
9748+
9749+
The returned band remains owned by the
9750+
GDALDataset and should not be deleted by the application.
9751+
9752+
@warning Contrary to GDALDataset::GetRasterBand(), the indexing here is
9753+
consistent with the conventions of C/C++, i.e. starting at 0.
9754+
9755+
@param iBand a band index between 0 and size()-1.
9756+
9757+
@return the band, or nullptr if iBand is out of range or an error occurs.
9758+
9759+
@since GDAL 3.12
9760+
*/
9761+
9762+
const GDALRasterBand *GDALDataset::ConstBands::operator[](int iBand) const
9763+
{
9764+
return m_poSelf->GetRasterBand(1 + iBand);
9765+
}
9766+
9767+
/************************************************************************/
9768+
/* operator[]() */
9769+
/************************************************************************/
9770+
9771+
/**
9772+
\brief Fetch a raster band by index.
9773+
9774+
The returned band remains owned by the
9775+
GDALDataset and should not be deleted by the application.
9776+
9777+
@warning Contrary to GDALDataset::GetRasterBand(), the indexing here is
9778+
consistent with the conventions of C/C++, i.e. starting at 0.
9779+
9780+
@param iBand a band index between 0 and size()-1.
9781+
9782+
@return the band, or nullptr if iBand is out of range or an error occurs.
9783+
9784+
@since GDAL 3.12
9785+
*/
9786+
9787+
const GDALRasterBand *GDALDataset::ConstBands::operator[](size_t iBand) const
9788+
{
9789+
return m_poSelf->GetRasterBand(1 + static_cast<int>(iBand));
9790+
}
9791+
96149792
/************************************************************************/
96159793
/* GetRootGroup() */
96169794
/************************************************************************/

0 commit comments

Comments
 (0)