RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
Optional.h
Go to the documentation of this file.
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 <concepts>
26#include <optional> // IWYU pragma: export
27
28namespace rawspeed {
29
30template <typename T> class Optional final {
31 // NOLINTNEXTLINE(rawspeed-no-std-optional): we're in the wrapper.
32 std::optional<T> impl;
33
34public:
35 Optional() = default;
36
37 template <typename U = T>
38 requires(!std::same_as<U, Optional<T>> && !std::same_as<U, Optional<T>&> &&
39 !std::same_as<U, Optional<T> &&> &&
40 !std::same_as<U, std::optional<T>>)
41 // NOLINTNEXTLINE(google-explicit-constructor)
42 Optional(U&& value) : impl(std::forward<U>(value)) {}
43
44 template <typename U = T>
45 requires(std::same_as<U, T>)
46 Optional<T>& operator=(U&& value) {
47 impl = std::forward<U>(value);
48 return *this;
49 }
50
51 template <typename... Args> T& emplace(Args&&... args) {
52 return impl.emplace(std::forward<Args>(args)...);
53 }
54
55 const T* operator->() const {
57 return &impl.value();
58 }
59
62 return &impl.value();
63 }
64
65 const T& operator*() const& {
67 return impl.value();
68 }
69
70 T& operator*() & {
72 return impl.value();
73 }
74
75 T&& operator*() && {
77 return std::move(impl.value());
78 }
79
80 const T&& operator*() const&& {
82 return std::move(impl.value());
83 }
84
85 [[nodiscard]] bool has_value() const RAWSPEED_READNONE {
86 return impl.has_value();
87 }
88
89 explicit operator bool() const { return has_value(); }
90
91 template <typename U> T value_or(U&& fallback) const& {
92 return impl.value_or(std::forward<U>(fallback));
93 }
94
95 void reset() { impl.reset(); }
96};
97
98template <typename T, typename U>
99bool operator==(const Optional<T>& lhs, const U& rhs) {
100 return lhs && *lhs == rhs;
101}
102
103template <typename T, typename U>
104bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
105 if (lhs.has_value() != rhs.has_value())
106 return false;
107 if (!lhs.has_value())
108 return true;
109 return *lhs == *rhs;
110}
111
112} // namespace rawspeed
#define invariant(expr)
Definition Invariant.h:27
const T && operator*() const &&
Definition Optional.h:80
T value_or(U &&fallback) const &
Definition Optional.h:91
T & emplace(Args &&... args)
Definition Optional.h:51
bool has_value() const RAWSPEED_READNONE
Definition Optional.h:85
T && operator*() &&
Definition Optional.h:75
std::optional< T > impl
Definition Optional.h:32
T & operator*() &
Definition Optional.h:70
const T & operator*() const &
Definition Optional.h:65
const T * operator->() const
Definition Optional.h:55
Optional(U &&value)
Definition Optional.h:42
throw T(buf.data())
bool operator==(const AlignedAllocator< T1, A1 > &, const AlignedAllocator< T2, A2 > &)