Hyper API for C++  0.0.16638
Hyper client library for C++ applications
optional.hpp
Go to the documentation of this file.
1 
5 #ifndef TABLEAU_HYPER_OPTIONAL_HPP
6 #define TABLEAU_HYPER_OPTIONAL_HPP
7 
8 #if !defined(__cplusplus) || (__cplusplus < 201703L) /* Use own optional if C++ is older than C++17 */
9 #define hyper_use_own_optional
10 #endif
11 
12 #ifdef hyper_use_own_optional
13 #include <exception>
14 #include <type_traits>
15 #include <utility>
16 #else
17 #include <optional>
18 #endif
19 
20 #ifdef hyper_use_own_optional
21 // Our optional surrogate does not support `constexpr`
22 #define CONSTEXPR_OPTIONAL const
23 #else
24 #define CONSTEXPR_OPTIONAL constexpr
25 #endif
26 
27 namespace hyperapi {
28 #ifndef hyper_use_own_optional /* C++17 or greater */
29 template <typename T>
30 using optional = std::optional<T>;
31 using bad_optional_access = std::bad_optional_access;
32 #else
33 
34 class bad_optional_access : public std::exception {
35  using std::exception::exception;
36 };
37 
39 template <typename T>
40 class optional {
41  private:
43  alignas(T) char data[sizeof(T)];
44 
46  bool exists = false;
47 
48  public:
50  using value_type = T;
51 
53  optional() noexcept = default;
54 
56  optional(const optional& other);
57 
59  optional(optional&& other);
60 
62  template <
63  typename U = value_type,
64  typename = typename std::enable_if<!std::is_same<typename std::decay<U>::type, optional<T>>::value>::type>
65  optional(U&& value);
66 
68  optional& operator=(const optional& other);
69 
71  optional& operator=(optional&& other);
72 
74  template <typename Other>
75  bool operator==(const optional<Other>& other) const noexcept {
76  return (exists == other.exists) && ((!exists) || (**this == *other));
77  }
79  template <typename Other>
80  bool operator!=(const optional<Other>& other) const noexcept { return !(*this == other); }
81 
83  ~optional() { reset(); }
84 
86  bool has_value() const noexcept { return exists; }
88  explicit operator bool() const noexcept { return exists; }
89 
91  T& value() & {
92  if (!*this) {
93  throw bad_optional_access{};
94  }
95  return **this;
96  }
98  const T& value() const& {
99  if (!*this) {
100  throw bad_optional_access{};
101  }
102  return **this;
103  }
105  T&& value() && {
106  if (!*this) {
107  throw bad_optional_access{};
108  }
109  return **this;
110  }
112  const T&& value() const&& {
113  if (!*this) {
114  throw bad_optional_access{};
115  }
116  return **this;
117  }
118 
120  template <typename U>
121  T value_or(U&& default_value) const& {
122  return bool(*this) ? **this : static_cast<T>(std::forward<U>(default_value));
123  }
124 
126  template <typename U>
127  T value_or(U&& default_value) && {
128  return bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(default_value));
129  }
130 
132  T* operator->() noexcept { return ptr(); }
134  const T* operator->() const noexcept { return ptr(); }
135 
137  const T& operator*() const& { return *ptr(); }
139  T& operator*() & { return *ptr(); }
141  const T&& operator*() const&& { return *ptr(); }
143  T&& operator*() && { return std::move(*ptr()); }
144 
146  void reset() noexcept;
148  void swap(optional& other);
150  template <typename... Args>
151  void emplace(Args&&... args);
152 
153  private:
155  template <typename... Args>
156  void create(Args&&... args);
157 
159  T* ptr() noexcept { return exists ? reinterpret_cast<T*>(data) : nullptr; }
161  const T* ptr() const noexcept { return exists ? reinterpret_cast<const T*>(data) : nullptr; }
162 };
163 
164 #endif
165 }
166 #include <hyperapi/impl/optional.impl.hpp>
167 #endif
hyperapi::optional::swap
void swap(optional &other)
Swap.
hyperapi::bad_optional_access
Surrogate for C++17 std::bad_optional_access
Definition: optional.hpp:34
hyperapi::optional::has_value
bool has_value() const noexcept
Checks whether *this contains a value.
Definition: optional.hpp:86
hyperapi::optional::operator!=
bool operator!=(const optional< Other > &other) const noexcept
Comparison.
Definition: optional.hpp:80
hyperapi::optional::optional
optional() noexcept=default
Constructor.
hyperapi::optional::operator->
const T * operator->() const noexcept
Value access.
Definition: optional.hpp:134
hyperapi::optional::value
T & value() &
Value access.
Definition: optional.hpp:91
hyperapi::optional::value
const T && value() const &&
Value access.
Definition: optional.hpp:112
hyperapi::optional::value_or
T value_or(U &&default_value) const &
Value or default.
Definition: optional.hpp:121
hyperapi::optional::operator*
T & operator*() &
Value access.
Definition: optional.hpp:139
hyperapi::optional::emplace
void emplace(Args &&... args)
Emplace.
hyperapi::optional::reset
void reset() noexcept
Reset.
hyperapi::optional
Surrogate for C++17 std::optional
Definition: optional.hpp:40
hyperapi::optional::operator->
T * operator->() noexcept
Value access.
Definition: optional.hpp:132
hyperapi::optional::operator*
T && operator*() &&
Value access.
Definition: optional.hpp:143
hyperapi::optional::value
T && value() &&
Value access.
Definition: optional.hpp:105
hyperapi::optional::operator*
const T && operator*() const &&
Value access.
Definition: optional.hpp:141
hyperapi
The primary namespace of the Hyper API for C++.
Definition: ByteSpan.hpp:15
hyperapi::optional::~optional
~optional()
Destructor.
Definition: optional.hpp:83
hyperapi::optional::value
const T & value() const &
Value access.
Definition: optional.hpp:98
hyperapi::optional::value_or
T value_or(U &&default_value) &&
Value or default.
Definition: optional.hpp:127
hyperapi::DatabaseName
Represents an escaped SQL database name.
Definition: DatabaseName.hpp:12
hyperapi::optional::operator*
const T & operator*() const &
Value access.
Definition: optional.hpp:137