ocpp 0.24.1
A C++ implementation of the Open Charge Point Protocol
custom_iterators.hpp
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
3
4#pragma once
5
6#include <memory>
7#include <vector>
8
9namespace ocpp {
10
11// This file contains the implementation of a couple of custom iterators, enabling the iteration and abstraction of more
12// complex containers. For example we want to be able to iterate a std::vector<std::unique_ptr<T>> and get references to
13// T from the iterator
14//
15// ForwardIterator<T> implements a custom iterator for type T that does not depend on any underlying container.
16// You can add this for your type by returning ForwardIterator<T> from begin() and end()
17// ForwardIterator can only be constructed by passing a ForwardIteratorBase derived struct in a unique_ptr.
18// ForwardIteratorBase is an abstract class that allows us to implement container specific functionality.
19// VectorOfUniquePtrIterator is an implementation of the ForwardIteratorBase specifically catered to the example of
20// std::vector<std:unique_ptr<T>>
21// So to implement the begin() and end() functions for your type, you could do the following:
22// std::vector<std::unique_ptr<T>> container;
23// ForwardIterator<T> begin() {
24// return ForwardIterator<T>(std::make_unique<VectorOfUniquePtrIterator<T>>(container.begin()));
25// }
26
28template <typename T> struct ForwardIteratorBase {
29 virtual ~ForwardIteratorBase() = default;
30
32 virtual T& deref() const = 0;
34 virtual void advance() = 0;
36 virtual bool not_equal(const ForwardIteratorBase& other) = 0;
37};
38
41template <typename T> struct ForwardIterator {
42 using iterator_category = std::forward_iterator_tag;
43 using difference_type = std::ptrdiff_t;
44 using value_type = T;
45 using pointer = value_type*;
46 using reference = value_type&;
48
50 explicit ForwardIterator(std::unique_ptr<base> it) : it{std::move(it)} {
51 }
52
54 reference operator*() const {
55 return it->deref();
56 };
57
60 it->advance();
61 return *this;
62 }
63
65 friend bool operator!=(const ForwardIterator& a, const ForwardIterator& b) {
66 return a.it->not_equal(*b.it);
67 };
68
69private:
70 std::unique_ptr<base> it;
71};
72
74template <typename T> struct VectorOfUniquePtrIterator : ForwardIteratorBase<T> {
75 using iterator_type = typename std::vector<std::unique_ptr<T>>::iterator;
77
78 explicit VectorOfUniquePtrIterator(iterator_type it) : it{it} {
79 }
80
81 T& deref() const override {
82 return *it->get();
83 }
84
85 void advance() override {
86 ++it;
87 }
88
89 bool not_equal(const base& other) override {
90 return it != dynamic_cast<const VectorOfUniquePtrIterator&>(other).it;
91 }
92
93private:
94 iterator_type it;
95};
96
97} // namespace ocpp
Abstract struct to implement to enable the use of the ForwardIterator<T>
Definition: custom_iterators.hpp:28
virtual bool not_equal(const ForwardIteratorBase &other)=0
Check for equality between this iterator and other.
virtual T & deref() const =0
Get a reference to the value pointed to by the iterator.
virtual void advance()=0
Increment the iterator once to the next position.
Helper struct that allows the use of an iterator in an interface, can be implemented using any forwar...
Definition: custom_iterators.hpp:41
friend bool operator!=(const ForwardIterator &a, const ForwardIterator &b)
Check for inequality between this a and b.
Definition: custom_iterators.hpp:65
reference operator*() const
Get a reference to the value pointed to by the iterator.
Definition: custom_iterators.hpp:54
ForwardIterator & operator++()
Increment the iterator once to the next position.
Definition: custom_iterators.hpp:59
ForwardIterator(std::unique_ptr< base > it)
Construct a new wrapper using any type that implements the abstract struct Base.
Definition: custom_iterators.hpp:50
Implementation for the ForwardIteratorBase based on a vector of unique_ptr with type T.
Definition: custom_iterators.hpp:74
T & deref() const override
Get a reference to the value pointed to by the iterator.
Definition: custom_iterators.hpp:81
bool not_equal(const base &other) override
Check for equality between this iterator and other.
Definition: custom_iterators.hpp:89
void advance() override
Increment the iterator once to the next position.
Definition: custom_iterators.hpp:85