swift
optional.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #ifndef SWIFT_MISC_OPTIONAL_H
7 #define SWIFT_MISC_OPTIONAL_H
8 
9 #include <utility>
10 
11 #include <QtGlobal>
12 
13 namespace swift::misc
14 {
15 
21  template <typename T>
22  class Optional
23  {
24  public:
26  Optional() noexcept = default;
27 
29  Optional(T value) noexcept(std::is_nothrow_move_constructible_v<T>)
30  {
31  new (m_data.bytes) T(std::move(value));
32  m_isValid = true;
33  }
34 
36  Optional(std::nullptr_t) noexcept {}
37 
39  Optional(const Optional &other) noexcept(std::is_nothrow_copy_constructible_v<T>)
40  {
41  if (other.m_isValid) { new (m_data.bytes) T(*other); }
42  m_isValid = other.m_isValid;
43  }
44 
46  Optional(Optional &&other) noexcept(std::is_nothrow_move_constructible_v<T>)
47  {
48  if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
49  m_isValid = other.m_isValid;
50  }
51 
53  Optional &operator=(std::nullptr_t) noexcept
54  {
55  reset();
56  return *this;
57  }
58 
60  Optional &operator=(const Optional &other) noexcept(std::is_nothrow_copy_constructible_v<T>)
61  {
62  reset();
63  if (other.m_isValid) { new (m_data.bytes) T(*other); }
64  m_isValid = other.m_isValid;
65  return *this;
66  }
67 
69  Optional &operator=(Optional &&other) noexcept(std::is_nothrow_move_constructible_v<T>)
70  {
71  reset();
72  if (other.m_isValid) { new (m_data.bytes) T(std::move(*other)); }
73  m_isValid = other.m_isValid;
74  return *this;
75  }
76 
79  {
80  if (m_isValid) { (*this)->~T(); }
81  }
82 
84  explicit operator bool() const noexcept { return m_isValid; }
85 
87  void reset() noexcept
88  {
89  if (m_isValid) { (*this)->~T(); }
90  m_isValid = false;
91  }
92 
94  T &operator*() { return dereference(); }
95 
97  const T &operator*() const { return dereference(); }
98 
100  T *operator->() { return &dereference(); }
101 
103  const T *operator->() const { return &dereference(); }
104 
105  private:
106  bool m_isValid = false;
107 
108  T &dereference()
109  {
110  Q_ASSERT(m_isValid);
111  return m_data.object;
112  }
113  const T &dereference() const
114  {
115  Q_ASSERT(m_isValid);
116  return m_data.object;
117  }
118  union Data
119  {
120  Data() {}
121  ~Data() {}
122  char bytes[sizeof(T)];
123  T object;
124  };
125  Data m_data;
126  };
127 
131  template <typename T>
132  void swap(Optional<T> &a, Optional<T> &b) noexcept(std::is_nothrow_swappable_v<T>)
133  {
134  if (a)
135  {
136  if (b)
137  {
138  using std::swap;
139  swap(*a, *b);
140  }
141  else
142  {
143  b = std::move(a);
144  a = nullptr;
145  }
146  }
147  else if (b)
148  {
149  a = std::move(b);
150  b = nullptr;
151  }
152  }
153 
154 } // namespace swift::misc
155 
156 #endif // SWIFT_MISC_OPTIONAL_H
Own implementation of std::optional.
Definition: optional.h:23
void reset() noexcept
If object is valid, destroy to make it invalid.
Definition: optional.h:87
~Optional()
Destructor.
Definition: optional.h:78
const T & operator*() const
Dereference operator, returns reference to contained value, undefined if there is no value contained.
Definition: optional.h:97
T & operator*()
Dereference operator, returns reference to contained value, undefined if there is no value contained.
Definition: optional.h:94
Optional & operator=(const Optional &other) noexcept(std::is_nothrow_copy_constructible_v< T >)
Copy assignment.
Definition: optional.h:60
T * operator->()
Indirection operator, returns pointer to contained value, undefined if there is no value contained.
Definition: optional.h:100
Optional & operator=(Optional &&other) noexcept(std::is_nothrow_move_constructible_v< T >)
Move assignment.
Definition: optional.h:69
Optional(std::nullptr_t) noexcept
Construct from a nullptr, equivalent to default constructor.
Definition: optional.h:36
Optional() noexcept=default
Default constructor.
Optional & operator=(std::nullptr_t) noexcept
Assign a nullptr.
Definition: optional.h:53
const T * operator->() const
Indirection operator, returns pointer to contained value, undefined if there is no value contained.
Definition: optional.h:103
Optional(Optional &&other) noexcept(std::is_nothrow_move_constructible_v< T >)
Move constructor.
Definition: optional.h:46
Optional(const Optional &other) noexcept(std::is_nothrow_copy_constructible_v< T >)
Copy constructor.
Definition: optional.h:39
Free functions in swift::misc.
void swap(Optional< T > &a, Optional< T > &b) noexcept(std::is_nothrow_swappable_v< T >)
Efficient swap for two Optional objects.
Definition: optional.h:132