Skip to content

Commit eb88c69

Browse files
authored
Merge pull request #599 from LebedevRI/optional
Ban `std::optional`
2 parents fb84d41 + acd5a0f commit eb88c69

26 files changed

+180
-78
lines changed

cmake/compiler-warnings-gcc.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ endif()
3636

3737
set (GCC_DISABLED_WARNING_FLAGS
3838
"unused-parameter"
39+
"maybe-uninitialized"
3940
"stringop-overflow" # bogus warnings at least as of GCC13
4041
"array-bounds" # bogus warnings at least as of GCC13
4142
)

fuzz/librawspeed/codes/PrefixCodeDecoder/Common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#pragma once
2222

2323
#include "adt/Array1DRef.h"
24+
#include "adt/Optional.h"
2425
#include "codes/AbstractPrefixCode.h"
2526
#include "codes/HuffmanCode.h"
2627
#include "codes/PrefixCode.h"
@@ -29,7 +30,6 @@
2930
#include "io/ByteStream.h"
3031
#include <cassert>
3132
#include <cstdint>
32-
#include <optional>
3333
#include <type_traits>
3434
#include <vector>
3535

@@ -147,7 +147,7 @@ template <typename T>
147147
static T createPrefixCodeDecoder(rawspeed::ByteStream& bs) {
148148
using CodeTag = typename T::Tag;
149149

150-
std::optional<T> ht;
150+
rawspeed::Optional<T> ht;
151151
if (bool huffmanCode = bs.getByte() != 0; huffmanCode)
152152
ht = createHuffmanPrefixCodeDecoderImpl<T, CodeTag>(bs);
153153
else

fuzz/librawspeed/decompressors/PentaxDecompressor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "decompressors/PentaxDecompressor.h"
2222
#include "MemorySanitizer.h"
2323
#include "adt/Casts.h"
24+
#include "adt/Optional.h"
2425
#include "common/RawImage.h"
2526
#include "common/RawspeedException.h"
2627
#include "fuzz/Common.h"
@@ -30,7 +31,6 @@
3031
#include <cassert>
3132
#include <cstdint>
3233
#include <cstdio>
33-
#include <optional>
3434

3535
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);
3636

@@ -45,7 +45,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
4545

4646
rawspeed::RawImage mRaw(CreateRawImage(bs));
4747

48-
std::optional<rawspeed::ByteStream> metaData;
48+
rawspeed::Optional<rawspeed::ByteStream> metaData;
4949

5050
const bool haveMetadata = bs.get<uint32_t>();
5151
if (haveMetadata) {

src/librawspeed/adt/Array2DRef.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323

2424
#include "adt/Array1DRef.h"
2525
#include "adt/Invariant.h"
26+
#include "adt/Optional.h"
2627
#include <cstddef>
27-
#include <optional>
2828
#include <type_traits>
2929
#include <vector>
3030

@@ -93,7 +93,7 @@ template <class T> class Array2DRef final {
9393
return {storage.data(), width, height};
9494
}
9595

96-
[[nodiscard]] std::optional<Array1DRef<T>> getAsArray1DRef() const;
96+
[[nodiscard]] Optional<Array1DRef<T>> getAsArray1DRef() const;
9797

9898
Array1DRef<T> operator[](int row) const;
9999

@@ -123,7 +123,7 @@ Array2DRef<T>::Array2DRef(T* data, const int width_, const int height_,
123123
}
124124

125125
template <class T>
126-
[[nodiscard]] inline std::optional<Array1DRef<T>>
126+
[[nodiscard]] inline Optional<Array1DRef<T>>
127127
Array2DRef<T>::getAsArray1DRef() const {
128128
// FIXME: this might be called for default-constructed `Array2DRef`,
129129
// and it really doesn't work for them.

src/librawspeed/adt/Optional.h

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
RawSpeed - RAW file decoder.
3+
4+
Copyright (C) 2024 Roman Lebedev
5+
6+
This library is free software; you can redistribute it and/or
7+
modify it under the terms of the GNU Lesser General Public
8+
License as published by the Free Software Foundation; either
9+
version 2 of the License, or (at your option) any later version.
10+
11+
This library 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 GNU
14+
Lesser General Public License for more details.
15+
16+
You should have received a copy of the GNU Lesser General Public
17+
License along with this library; if not, write to the Free Software
18+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19+
*/
20+
21+
#pragma once
22+
23+
#include "rawspeedconfig.h"
24+
#include "adt/Invariant.h"
25+
#include <optional> // IWYU pragma: export
26+
27+
namespace rawspeed {
28+
29+
template <typename T> class Optional final {
30+
std::optional<T> impl;
31+
32+
public:
33+
Optional() = default;
34+
35+
template <typename U = T>
36+
requires(!std::same_as<U, Optional<T>> && !std::same_as<U, Optional<T>&> &&
37+
!std::same_as<U, Optional<T> &&> &&
38+
!std::same_as<U, std::optional<T>>)
39+
// NOLINTNEXTLINE(google-explicit-constructor)
40+
Optional(U&& value) : impl(std::forward<U>(value)) {}
41+
42+
template <typename U = T>
43+
requires(std::same_as<U, T>)
44+
Optional<T>& operator=(U&& value) {
45+
impl = std::forward<U>(value);
46+
return *this;
47+
}
48+
49+
template <typename... Args> T& emplace(Args&&... args) {
50+
return impl.emplace(std::forward<Args>(args)...);
51+
}
52+
53+
const T* operator->() const {
54+
invariant(has_value());
55+
return &impl.value();
56+
}
57+
58+
T* operator->() {
59+
invariant(has_value());
60+
return &impl.value();
61+
}
62+
63+
const T& operator*() const& {
64+
invariant(has_value());
65+
return impl.value();
66+
}
67+
68+
T& operator*() & {
69+
invariant(has_value());
70+
return impl.value();
71+
}
72+
73+
T&& operator*() && {
74+
invariant(has_value());
75+
return std::move(impl.value());
76+
}
77+
78+
const T&& operator*() const&& {
79+
invariant(has_value());
80+
return std::move(impl.value());
81+
}
82+
83+
[[nodiscard]] bool has_value() const RAWSPEED_READNONE {
84+
return impl.has_value();
85+
}
86+
87+
explicit operator bool() const { return has_value(); }
88+
89+
void reset() { impl.reset(); }
90+
};
91+
92+
template <typename T, typename U>
93+
bool operator==(const Optional<T>& lhs, const U& rhs) {
94+
return lhs && *lhs == rhs;
95+
}
96+
97+
template <typename T, typename U>
98+
bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
99+
if (lhs.has_value() != rhs.has_value())
100+
return false;
101+
if (!lhs.has_value())
102+
return true;
103+
return *lhs == *rhs;
104+
}
105+
106+
} // namespace rawspeed

src/librawspeed/codes/PrefixCodeTreeDecoder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
#pragma once
2323

2424
#include "adt/Invariant.h"
25+
#include "adt/Optional.h"
2526
#include "codes/AbstractPrefixCodeDecoder.h"
2627
#include "codes/BinaryPrefixTree.h"
2728
#include "decoders/RawDecoderException.h"
2829
#include "io/BitStream.h"
2930
#include <cassert>
30-
#include <optional>
3131
#include <tuple>
3232
#include <utility>
3333

@@ -57,8 +57,7 @@ class PrefixCodeTreeDecoder : public AbstractPrefixCodeDecoder<CodeTag> {
5757
const auto* top = &(tree.root->getAsBranch());
5858

5959
auto walkBinaryTree = [&partial, &top](bool bit)
60-
-> std::optional<
61-
std::pair<typename Base::CodeSymbol, int /*codeValue*/>> {
60+
-> Optional<std::pair<typename Base::CodeSymbol, int /*codeValue*/>> {
6261
partial.code <<= 1;
6362
partial.code |= bit;
6463
partial.code_len++;

src/librawspeed/common/BayerPhase.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#pragma once
2222

2323
#include "adt/Array2DRef.h"
24+
#include "adt/Optional.h"
2425
#include "adt/Point.h"
2526
#include "metadata/ColorFilterArray.h"
2627
#include <algorithm>
@@ -29,7 +30,6 @@
2930
#include <cmath>
3031
#include <cstdlib>
3132
#include <iterator>
32-
#include <optional>
3333
#include <utility>
3434

3535
namespace rawspeed {
@@ -127,7 +127,7 @@ inline std::array<T, 4> applyStablePhaseShift(std::array<T, 4> srcData,
127127
return tgtData;
128128
}
129129

130-
inline std::optional<BayerPhase> getAsBayerPhase(const ColorFilterArray& CFA) {
130+
inline Optional<BayerPhase> getAsBayerPhase(const ColorFilterArray& CFA) {
131131
if (CFA.getSize() != iPoint2D(2, 2))
132132
return {};
133133

src/librawspeed/common/DngOpcodes.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "adt/Casts.h"
2626
#include "adt/CroppedArray2DRef.h"
2727
#include "adt/Mutex.h"
28+
#include "adt/Optional.h"
2829
#include "adt/Point.h"
2930
#include "common/Common.h"
3031
#include "common/RawImage.h"
@@ -41,7 +42,6 @@
4142
#include <iterator>
4243
#include <limits>
4344
#include <memory>
44-
#include <optional>
4545
#include <tuple>
4646
#include <type_traits>
4747
#include <utility>
@@ -743,7 +743,7 @@ DngOpcodes::constructor(const RawImage& ri, ByteStream& bs,
743743

744744
// ALL opcodes specified in DNG Specification MUST be listed here.
745745
// however, some of them might not be implemented.
746-
std::optional<std::pair<const char*, DngOpcodes::constructor_t>>
746+
Optional<std::pair<const char*, DngOpcodes::constructor_t>>
747747
DngOpcodes::Map(uint32_t code) {
748748
switch (code) {
749749
case 1U:

src/librawspeed/common/DngOpcodes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222
#pragma once
2323

24+
#include "adt/Optional.h"
2425
#include <cstdint>
2526
#include <memory>
26-
#include <optional>
2727
#include <utility>
2828
#include <vector>
2929

@@ -65,7 +65,7 @@ class DngOpcodes final {
6565

6666
using constructor_t = std::unique_ptr<DngOpcode> (*)(
6767
const RawImage& ri, ByteStream& bs, iRectangle2D& integrated_subimg);
68-
static std::optional<std::pair<const char*, DngOpcodes::constructor_t>>
68+
static Optional<std::pair<const char*, DngOpcodes::constructor_t>>
6969
Map(uint32_t code);
7070
};
7171

src/librawspeed/common/XTransPhase.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
#pragma once
2222

2323
#include "adt/Array2DRef.h"
24+
#include "adt/Optional.h"
2425
#include "adt/Point.h"
2526
#include "metadata/ColorFilterArray.h"
2627
#include <array>
2728
#include <cassert>
2829
#include <cmath>
2930
#include <cstdlib>
30-
#include <optional>
3131

3232
namespace rawspeed {
3333

@@ -70,8 +70,7 @@ inline std::array<CFAColor, 6 * 6> getAsCFAColors(XTransPhase p) {
7070
return applyPhaseShift(basePat, basePhase, /*tgtPhase=*/p);
7171
}
7272

73-
inline std::optional<XTransPhase>
74-
getAsXTransPhase(const ColorFilterArray& CFA) {
73+
inline Optional<XTransPhase> getAsXTransPhase(const ColorFilterArray& CFA) {
7574
if (CFA.getSize() != iPoint2D(6, 6))
7675
return {};
7776

0 commit comments

Comments
 (0)