Line | Branch | Exec | Source |
---|---|---|---|
1 | // SPDX-FileCopyrightText: 2023 Carl Zeiss Microscopy GmbH | ||
2 | // | ||
3 | // SPDX-License-Identifier: MIT | ||
4 | |||
5 | #pragma once | ||
6 | |||
7 | #include <functional> | ||
8 | #include <vector> | ||
9 | #include "types.h" | ||
10 | |||
11 | namespace imgdoc2 | ||
12 | { | ||
13 | /// Definition of the interface representing a "tile coordinate". This interface is immutable and does not | ||
14 | /// allow to mutate the data. | ||
15 | class ITileCoordinate | ||
16 | { | ||
17 | public: | ||
18 | /// Attempts to get the value for the specified dimensions. | ||
19 | /// \param dim The dimension to query. | ||
20 | /// \param [in,out] coordVal If non-null and the call is successful, the coordinate value is put here. | ||
21 | /// \returns True if it succeeds, false if it fails. | ||
22 | virtual bool TryGetCoordinate(imgdoc2::Dimension dim, int* coordVal) const = 0; | ||
23 | |||
24 | /// Enum the dimensions and the coordinates represented by this object. | ||
25 | /// \param f A functor which is called for each item, passing in the dimension and the coordinate. If the functor | ||
26 | /// returns false, the enumeration is ended. | ||
27 | virtual void EnumCoordinates(const std::function<bool(imgdoc2::Dimension, int)>& f) const = 0; | ||
28 | |||
29 | 94780 | virtual ~ITileCoordinate() = default; | |
30 | |||
31 | /// Enum the dimensions represented in this object. | ||
32 | /// \param f A functor which is called for each dimension. If the functor | ||
33 | /// returns false, the enumeration is ended. | ||
34 | 4 | inline void EnumDimensions(const std::function<bool(imgdoc2::Dimension)>& f) const | |
35 | { | ||
36 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
8 | this->EnumCoordinates([&](imgdoc2::Dimension d, int v)->bool {return f(d); }); |
37 | 4 | } | |
38 | |||
39 | /// Determine if the two specified ITileCoordinate objects are equal. Equality is defined as having the same | ||
40 | /// set of dimensions and the same values for each dimension. In addition, object identity is also regarded | ||
41 | /// as equality, but comparison with nullptr is not regarded as equality (also - two nullptrs are regarded as | ||
42 | /// unequal). | ||
43 | /// | ||
44 | /// \param a The first ITileCoordinate to compare. | ||
45 | /// \param b The second ITileCoordinate to compare. | ||
46 | /// | ||
47 | /// \returns True if equal, false if not. | ||
48 | 28 | [[nodiscard]] static bool AreEqual(const ITileCoordinate* a, const ITileCoordinate* b) | |
49 | { | ||
50 |
4/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 22 times.
|
28 | if (a == nullptr || b == nullptr) |
51 | { | ||
52 | 6 | return false; | |
53 | } | ||
54 | |||
55 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 20 times.
|
22 | if (a == b) |
56 | { | ||
57 | 2 | return true; | |
58 | } | ||
59 | |||
60 | 20 | bool are_equal = true; | |
61 | |||
62 | // first, we enumerate the dimensions in a and check if they are also in b (and have the same value) | ||
63 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
20 | a->EnumCoordinates( |
64 | 20 | [=, &are_equal](imgdoc2::Dimension dimension, int value_a)->bool | |
65 | { | ||
66 | int value_b; | ||
67 |
3/4✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 40 times.
|
44 | if (!b->TryGetCoordinate(dimension, &value_b)) |
68 | { | ||
69 | 4 | are_equal = false; | |
70 | 4 | return false; | |
71 | } | ||
72 | |||
73 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 36 times.
|
40 | if (value_a != value_b) |
74 | { | ||
75 | 4 | are_equal = false; | |
76 | 4 | return false; | |
77 | } | ||
78 | |||
79 | 36 | return true; | |
80 | }); | ||
81 | |||
82 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
|
20 | if (are_equal) |
83 | { | ||
84 | // Ok, this means that for all dimensions present in a, we have the same value in b (and dimension is also present in b of course). | ||
85 | // However, it may be that b has more dimensions than a. So we need to check that as well (but we don't need to check the equality | ||
86 | // of the values anymore this time). | ||
87 |
1/2✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
|
12 | b->EnumCoordinates( |
88 | 24 | [=, &are_equal](imgdoc2::Dimension dimension, int)->bool | |
89 | { | ||
90 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 24 times.
|
26 | if (!a->TryGetCoordinate(dimension, nullptr)) |
91 | { | ||
92 | 2 | are_equal = false; | |
93 | 2 | return false; | |
94 | } | ||
95 | |||
96 | 24 | return true; | |
97 | }); | ||
98 | } | ||
99 | |||
100 | 20 | return are_equal; | |
101 | } | ||
102 | |||
103 | /// Equality operator. | ||
104 | /// \param other The other object to compare to. | ||
105 | /// \returns True if equal, false if not. | ||
106 | 10 | bool operator==(const ITileCoordinate& other) const | |
107 | { | ||
108 | 10 | return ITileCoordinate::AreEqual(this, &other); | |
109 | } | ||
110 | |||
111 | /// Inequality operator. | ||
112 | /// \param other The other object to compare to. | ||
113 | /// \returns True if unequal, false if not. | ||
114 | 10 | bool operator!=(const ITileCoordinate& other) const | |
115 | { | ||
116 | 10 | return !ITileCoordinate::AreEqual(this, &other); | |
117 | } | ||
118 | |||
119 | /// Gets a vector with the dimensions contained in this object. | ||
120 | /// \returns The dimensions. | ||
121 | 4 | [[nodiscard]] std::vector<imgdoc2::Dimension> GetDimensions() const | |
122 | { | ||
123 | 4 | std::vector<imgdoc2::Dimension> vec; | |
124 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | this->EnumDimensions( |
125 | 4 | [&vec](imgdoc2::Dimension d)->bool | |
126 | { | ||
127 | 4 | vec.push_back(d); | |
128 | 4 | return true; | |
129 | }); | ||
130 | |||
131 | 4 | return vec; | |
132 | ✗ | } | |
133 | |||
134 | /// Queries if the specified value is a legal dimension. Legal dimensions are a-z and A-Z. | ||
135 | /// \param dimension The dimension. | ||
136 | /// \returns True if the dimension is valid, false if not. | ||
137 | [[nodiscard]] inline static bool IsValidDimension(imgdoc2::Dimension dimension) | ||
138 | { | ||
139 | return imgdoc2::IsDimensionValid(dimension); | ||
140 | } | ||
141 | }; | ||
142 | |||
143 | /// This interface provides modify access to the object and allows to mutate the object. | ||
144 | class ITileCoordinateMutate : public ITileCoordinate | ||
145 | { | ||
146 | public: | ||
147 | /// Clears this object to its blank/initial state. | ||
148 | virtual void Clear() = 0; | ||
149 | |||
150 | /// Sets the specified coordinate value for the specified dimension. | ||
151 | /// \param d The dimension. | ||
152 | /// \param value The value. | ||
153 | virtual void Set(imgdoc2::Dimension d, int value) = 0; | ||
154 | |||
155 | 94780 | ~ITileCoordinateMutate() override = default; | |
156 | }; | ||
157 | } | ||
158 |