openPMD-api
 
Loading...
Searching...
No Matches
IteratorTraits.hpp
1/* Copyright 2024 Franz Poeschel
2 *
3 * This file is part of openPMD-api.
4 *
5 * openPMD-api is free software: you can redistribute it and/or modify
6 * it under the terms of of either the GNU General Public License or
7 * the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * openPMD-api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License and the GNU Lesser General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * and the GNU Lesser General Public License along with openPMD-api.
19 * If not, see <http://www.gnu.org/licenses/>.
20 */
21#pragma once
22
23#include "openPMD/Iteration.hpp"
24#include "openPMD/backend/Writable.hpp"
25
26#include <memory>
27
28/*
29 * Public header due to use in OpaqueSeriesIterator type which is the public
30 * iterator type of Snapshots class.
31 */
32
33namespace openPMD
34{
35/*
36 * Abstract class that can be used as an abstract interface to an opaque
37 * iterator implementation
38 *
39 * This has renamed operator names for two reasons:
40 *
41 * 1. Name shadowing of default implementations is too finnicky.
42 * 2. The return type for the actual operators should be a reference to the
43 * child class, but for an Interface we need a common return type.
44 *
45 * For returning a reference to the child class, we need a CRT-style template to
46 * know the type. That does not work for an interface. As a result, this generic
47 * Iterator interface is split in two parts, class DynamicSeriesIterator which
48 * can be used generically without specifying the child class. All methods that
49 * need to know the child class type are put into the CRT-style class template
50 * AbstractSeriesIterator below.
51 */
52template <
53 typename value_type =
54 Container<Iteration, Iteration::IterationIndex_t>::value_type>
56{
57public:
58 using difference_type = Iteration::IterationIndex_t;
59 virtual ~DynamicSeriesIterator() = 0;
60
61protected:
62 template <typename>
63 friend class OpaqueSeriesIterator;
64
65 // dereference
66 virtual value_type const &dereference_operator() const = 0;
67 virtual value_type &dereference_operator();
68
69 // increment/decrement
70 virtual DynamicSeriesIterator &increment_operator() = 0;
71 virtual DynamicSeriesIterator &decrement_operator() = 0;
72
73 // comparison
74 virtual bool equality_operator(DynamicSeriesIterator const &) const = 0;
75
76 virtual std::unique_ptr<DynamicSeriesIterator> clone() const = 0;
77};
78/*
79 * Class template with default method implementations for iterators.
80 * Complementary class to above class DynamicSeriesIterator, containing those
81 * methods that have the specific Iterator type in their type specification. See
82 * the documentation for DynamicSeriesIterator for more details.
83 * No virtual classes since there is no use.
84 * Commented methods must be implemented by child classes.
85 * Implement as `class MyIterator : public AbstractSeriesIterator<MyIterator>`
86 * Use `using AbstractSeriesIterator<MyIterator>::operator-` to pull default
87 * implementations.
88 */
89template <
90 typename ChildClass,
91 typename value_type_in = typename ChildClass::value_type>
92class AbstractSeriesIterator : public DynamicSeriesIterator<value_type_in>
93{
94public:
95 using difference_type = Iteration::IterationIndex_t;
96 using value_type = value_type_in;
97
98 ~AbstractSeriesIterator() override;
99
100 /*
101 * Default definitions that can be pulled in implementing child classes with
102 * `using` declarations. Does not work for overloaded methods due to
103 * compiler bugs in ICPC, hence e.g. `default_increment_operator` instead of
104 * `operator++`.
105 */
106
107 // dereference
108 // value_type const &operator*() const = 0;
109 // value_type &operator*() = 0;
110 auto operator->() const -> value_type const *;
111 auto operator->() -> value_type *;
112
113 // increment/decrement
114 // ChildClass &operator++();
115 // ChildClass &operator--();
116 // ChildClass &operator++(int);
117 // ChildClass &operator--(int);
118 auto default_increment_operator(int) -> ChildClass;
119 auto default_decrement_operator(int) -> ChildClass;
120
121 // comparison
122 // bool operator==(ChildClass const &) const = 0;
123 bool operator!=(ChildClass const &) const;
124
125 /*************
126 * overrides *
127 *************/
128
129protected:
131 // dereference
132 using parent_t::dereference_operator;
133 auto dereference_operator() const -> value_type const & override;
134
135 // increment/decrement
136 auto increment_operator() -> parent_t & override;
137 auto decrement_operator() -> parent_t & override;
138
139 // comparison
140 auto equality_operator(parent_t const &) const -> bool override;
141
142 auto clone() const -> std::unique_ptr<parent_t> override;
143
144private:
145 ChildClass *this_child();
146 ChildClass const *this_child() const;
147};
148
149template <typename ChildClass>
150ChildClass operator+(
151 Iteration::IterationIndex_t, AbstractSeriesIterator<ChildClass> const &);
152template <typename ChildClass>
153ChildClass
154operator+(Iteration::IterationIndex_t, AbstractSeriesIterator<ChildClass> &);
155template <typename ChildClass>
156ChildClass operator-(
157 Iteration::IterationIndex_t, AbstractSeriesIterator<ChildClass> const &);
158template <typename ChildClass>
159ChildClass
160operator-(Iteration::IterationIndex_t, AbstractSeriesIterator<ChildClass> &);
161} // namespace openPMD
Definition IteratorTraits.hpp:93
Definition IteratorTraits.hpp:56
Public definitions of openPMD-api.
Definition Date.cpp:29