| 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 |