Coverage Report

Created: 2026-04-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/port/cpl_enumerate.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  CPL - Common Portability Library
4
 * Purpose:  Collection enumerator
5
 * Author:   Even Rouault, even.rouault at spatialys.com
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2025, Even Rouault <even.rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#ifndef CPL_ENUMERATE_H
14
#define CPL_ENUMERATE_H
15
16
#include <cstddef>   // size_t
17
#include <iterator>  // std::begin(), std::end()
18
#include <utility>   // std::declval(), std::pair
19
20
namespace cpl
21
{
22
23
//! @cond Doxygen_Suppress
24
25
template <class T> class Enumerator
26
{
27
  public:
28
    using TIter = decltype(std::begin(std::declval<T &>()));
29
30
    class iterator
31
    {
32
      public:
33
0
        explicit inline iterator(const TIter &it) : m_iter(it)
34
0
        {
35
0
        }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::iterator::iterator(OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*>::Iterator const&)
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::iterator::iterator(std::__1::__wrap_iter<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>*> const&)
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::iterator::iterator(std::__1::__wrap_iter<int*> const&)
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::iterator::iterator(std::__1::__wrap_iter<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*> const&)
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::iterator::iterator(std::__1::__wrap_iter<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc const*> const&)
36
37
        inline bool operator==(const iterator &other) const
38
        {
39
            return m_iter == other.m_iter;
40
        }
41
42
        inline bool operator!=(const iterator &other) const
43
0
        {
44
0
            return m_iter != other.m_iter;
45
0
        }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::iterator::operator!=(cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::iterator const&) const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::iterator::operator!=(cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::iterator const&) const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::iterator::operator!=(cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::iterator const&) const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::iterator::operator!=(cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::iterator const&) const
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::iterator::operator!=(cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::iterator const&) const
46
47
        inline iterator &operator++()
48
0
        {
49
0
            ++m_index;
50
0
            ++m_iter;
51
0
            return *this;
52
0
        }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::iterator::operator++()
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::iterator::operator++()
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::iterator::operator++()
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::iterator::operator++()
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::iterator::operator++()
53
54
        inline iterator operator++(int)
55
        {
56
            iterator before = *this;
57
            ++(*this);
58
            return before;
59
        }
60
61
        inline auto operator*() const
62
0
        {
63
0
            return std::pair<size_t, decltype(*m_iter) &>(m_index, *m_iter);
64
0
        }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::iterator::operator*() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::iterator::operator*() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::iterator::operator*() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::iterator::operator*() const
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::iterator::operator*() const
65
66
      private:
67
        TIter m_iter;
68
        size_t m_index = 0;
69
    };
70
71
0
    explicit inline Enumerator(T &iterable) : m_iterable(iterable)
72
0
    {
73
0
    }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::Enumerator(OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const&)
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::Enumerator(std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > >&)
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::Enumerator(std::__1::vector<int, std::__1::allocator<int> >&)
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::Enumerator(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&)
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::Enumerator(std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const&)
74
75
    inline iterator begin() const
76
0
    {
77
0
        return iterator(std::begin(m_iterable));
78
0
    }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::begin() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::begin() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::begin() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::begin() const
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::begin() const
79
80
    inline iterator end() const
81
0
    {
82
        // We could initialize the m_index to SIZE_T_MAX, but this does not
83
        // really matter as iterator comparison is done on the underlying
84
        // iterator and not the index.
85
0
        return iterator(std::end(m_iterable));
86
0
    }
Unexecuted instantiation: cpl::Enumerator<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>::end() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >::end() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<int, std::__1::allocator<int> > >::end() const
Unexecuted instantiation: cpl::Enumerator<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >::end() const
Unexecuted instantiation: gdalalg_vector_concat.cpp:cpl::Enumerator<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>::end() const
87
88
  private:
89
    T &m_iterable;
90
};
91
92
//! @endcond
93
94
/** Function returning an eumerator whose values are
95
 * a std::pair of (index: size_t, value: iterable::value_type).
96
 *
97
 * This is similar to Python enumerate() function and C++23
98
 * std::ranges::enumerate() (https://en.cppreference.com/w/cpp/ranges/enumerate_view.html)
99
 *
100
 * \since GDAL 3.13
101
 */
102
template <class T> inline auto enumerate(T &iterable)
103
0
{
104
0
    return Enumerator<T>(iterable);
105
0
}
Unexecuted instantiation: auto cpl::enumerate<OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const>(OGRFeatureDefn::Fields<OGRFeatureDefn const*, OGRFieldDefn const*> const&)
Unexecuted instantiation: auto cpl::enumerate<std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > > >(std::__1::vector<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int>, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, int> > >&)
Unexecuted instantiation: auto cpl::enumerate<std::__1::vector<int, std::__1::allocator<int> > >(std::__1::vector<int, std::__1::allocator<int> >&)
Unexecuted instantiation: auto cpl::enumerate<std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > >(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >&)
Unexecuted instantiation: gdalalg_vector_concat.cpp:auto cpl::enumerate<std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const>(std::__1::vector<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc, std::__1::allocator<GDALVectorConcatAlgorithm::RunStep(GDALPipelineStepRunContext&)::LayerDesc> > const&)
106
107
}  // namespace cpl
108
109
#endif