26#ifndef FORTRAN_COMMON_OPTIONAL_H
27#define FORTRAN_COMMON_OPTIONAL_H
32#if !defined(STD_OPTIONAL_UNSUPPORTED) && \
33 (defined(__CUDACC__) || defined(__CUDA__)) && defined(__CUDA_ARCH__)
34#define STD_OPTIONAL_UNSUPPORTED 1
37#define FORTRAN_OPTIONAL_INLINE_WITH_ATTRS inline RT_API_ATTRS
38#define FORTRAN_OPTIONAL_INLINE inline
39#define FORTRAN_OPTIONAL_INLINE_VAR inline
43#if STD_OPTIONAL_UNSUPPORTED
46 constexpr explicit nullopt_t() =
default;
50FORTRAN_OPTIONAL_INLINE_VAR
constexpr nullopt_t nullopt{};
55template <
typename T>
class optional {
56 template <typename U, bool = !std::is_trivially_destructible<U>::value>
57 struct OptionalStorage {
65 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS ~OptionalStorage() { reset(); }
67 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr OptionalStorage() : empty() {}
69 template <
typename... Args>
70 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr explicit OptionalStorage(
71 std::in_place_t, Args &&...args)
72 : stored_value(std::forward<Args>(args)...) {}
74 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr void reset() {
83 template <
typename U>
struct OptionalStorage<U, false> {
91 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr OptionalStorage() : empty() {}
93 template <
typename... Args>
94 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr explicit OptionalStorage(
95 std::in_place_t, Args &&...args)
96 : stored_value(std::forward<Args>(args)...) {}
98 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr void reset() {
103 OptionalStorage<T> storage;
110 FORTRAN_OPTIONAL_INLINE
constexpr optional() =
default;
111 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional(nullopt_t) {}
113 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional(
const T &t)
114 : storage(std::in_place, t) {
115 storage.in_use =
true;
117 FORTRAN_OPTIONAL_INLINE
constexpr optional(
const optional &) =
default;
119 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional(T &&t)
120 : storage(std::in_place, std::move(t)) {
121 storage.in_use =
true;
123 FORTRAN_OPTIONAL_INLINE
constexpr optional(optional &&O) =
default;
125 template <
typename... ArgTypes>
126 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional(
127 std::in_place_t, ArgTypes &&...Args)
128 : storage(std::in_place, std::forward<ArgTypes>(Args)...) {
129 storage.in_use =
true;
132 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional &operator=(T &&t) {
133 storage.stored_value = std::move(t);
134 storage.in_use =
true;
138 FORTRAN_OPTIONAL_INLINE
constexpr optional &operator=(optional &&) =
default;
140 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional &operator=(
const T &t) {
141 storage.stored_value = t;
142 storage.in_use =
true;
146 FORTRAN_OPTIONAL_INLINE
constexpr optional &operator=(
147 const optional &) =
default;
149 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr void reset() { storage.reset(); }
151 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr const T &value() const & {
152 return storage.stored_value;
155 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T &value() & {
156 return storage.stored_value;
159 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr explicit operator bool()
const {
160 return storage.in_use;
162 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr bool has_value()
const {
163 return storage.in_use;
165 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr const T *operator->()
const {
166 return &storage.stored_value;
168 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T *operator->() {
169 return &storage.stored_value;
171 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr const T &operator*() const & {
172 return storage.stored_value;
174 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T &operator*() & {
175 return storage.stored_value;
178 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T &&value() && {
179 return std::move(storage.stored_value);
181 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T &&operator*() && {
182 return std::move(storage.stored_value);
185 template <
typename VT>
186 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T value_or(
187 VT &&default_value)
const & {
188 return storage.in_use ? storage.stored_value
189 :
static_cast<T
>(std::forward<VT>(default_value));
192 template <
typename VT>
193 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr T value_or(
194 VT &&default_value) && {
195 return storage.in_use ? std::move(storage.stored_value)
196 : static_cast<T>(std::forward<VT>(default_value));
199 template <
typename... ArgTypes>
200 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
201 std::enable_if_t<std::is_constructible_v<T, ArgTypes &&...>, T &>
202 emplace(ArgTypes &&...args) {
204 new (
reinterpret_cast<void *
>(std::addressof(storage.stored_value)))
205 T(std::forward<ArgTypes>(args)...);
206 storage.in_use =
true;
210 template <
typename U = T,
211 std::enable_if_t<(std::is_constructible_v<T, U &&> &&
212 !std::is_same_v<std::decay_t<U>, std::in_place_t> &&
213 !std::is_same_v<std::decay_t<U>, optional> &&
214 std::is_convertible_v<U &&, T>),
216 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
constexpr optional(U &&value) {
217 new (
reinterpret_cast<void *
>(std::addressof(storage.stored_value)))
218 T(std::forward<U>(value));
219 storage.in_use =
true;
222 template <
typename U = T,
223 std::enable_if_t<(std::is_constructible_v<T, U &&> &&
224 !std::is_same_v<std::decay_t<U>, std::in_place_t> &&
225 !std::is_same_v<std::decay_t<U>, optional> &&
226 !std::is_convertible_v<U &&, T>),
228 FORTRAN_OPTIONAL_INLINE_WITH_ATTRS
explicit constexpr optional(U &&value) {
229 new (
reinterpret_cast<void *
>(std::addressof(storage.stored_value)))
230 T(std::forward<U>(value));
231 storage.in_use =
true;
Definition bit-population-count.h:20