proxygen
Optional.h
Go to the documentation of this file.
1 /*
2  * Copyright 2012-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 /*
19  * Optional - For conditional initialization of values, like boost::optional,
20  * but with support for move semantics and emplacement. Reference type support
21  * has not been included due to limited use cases and potential confusion with
22  * semantics of assignment: Assigning to an optional reference could quite
23  * reasonably copy its value or redirect the reference.
24  *
25  * Optional can be useful when a variable might or might not be needed:
26  *
27  * Optional<Logger> maybeLogger = ...;
28  * if (maybeLogger) {
29  * maybeLogger->log("hello");
30  * }
31  *
32  * Optional enables a 'null' value for types which do not otherwise have
33  * nullability, especially useful for parameter passing:
34  *
35  * void testIterator(const unique_ptr<Iterator>& it,
36  * initializer_list<int> idsExpected,
37  * Optional<initializer_list<int>> ranksExpected = none) {
38  * for (int i = 0; it->next(); ++i) {
39  * EXPECT_EQ(it->doc().id(), idsExpected[i]);
40  * if (ranksExpected) {
41  * EXPECT_EQ(it->doc().rank(), (*ranksExpected)[i]);
42  * }
43  * }
44  * }
45  *
46  * Optional models OptionalPointee, so calling 'get_pointer(opt)' will return a
47  * pointer to nullptr if the 'opt' is empty, and a pointer to the value if it is
48  * not:
49  *
50  * Optional<int> maybeInt = ...;
51  * if (int* v = get_pointer(maybeInt)) {
52  * cout << *v << endl;
53  * }
54  */
55 
56 #include <cstddef>
57 #include <functional>
58 #include <new>
59 #include <stdexcept>
60 #include <type_traits>
61 #include <utility>
62 
63 #include <folly/Portability.h>
64 #include <folly/Traits.h>
65 #include <folly/Utility.h>
66 #include <folly/lang/Exception.h>
67 
68 namespace folly {
69 
70 template <class Value>
71 class Optional;
72 
73 namespace detail {
74 template <class Value>
76 } // namespace detail
77 
78 struct None {
79  enum class _secret { _token };
80 
85  explicit constexpr None(_secret) {}
86 };
88 
89 class FOLLY_EXPORT OptionalEmptyException : public std::runtime_error {
90  public:
92  : std::runtime_error("Empty Optional cannot be unwrapped") {}
93 };
94 
95 template <class Value>
96 class Optional {
97  public:
98  typedef Value value_type;
99 
100  static_assert(
102  "Optional may not be used with reference types");
103  static_assert(
105  "Optional may not be used with abstract types");
106 
108 
111  if (src.hasValue()) {
112  construct(src.value());
113  }
114  }
115 
117  std::is_nothrow_move_constructible<Value>::value) {
118  if (src.hasValue()) {
119  construct(std::move(src.value()));
120  src.clear();
121  }
122  }
123 
124  FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(const None&) noexcept {}
125 
126  FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(Value&& newValue) noexcept(
127  std::is_nothrow_move_constructible<Value>::value) {
128  construct(std::move(newValue));
129  }
130 
131  FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(const Value& newValue) noexcept(
133  construct(newValue);
134  }
135 
139  template <typename Null = std::nullptr_t>
140  FOLLY_CPP14_CONSTEXPR /* implicit */
141  Optional(typename std::enable_if<
144  Null>::type) noexcept {}
145 
146  template <typename... Args>
148  std::is_nothrow_constructible<Value, Args...>::value)
149  : Optional{PrivateConstructor{}, std::forward<Args>(args)...} {}
150 
151  template <typename U, typename... Args>
153  in_place_t,
154  std::initializer_list<U> il,
155  Args&&... args) noexcept(std::
156  is_nothrow_constructible<
157  Value,
158  std::initializer_list<U>,
159  Args...>::value)
160  : Optional{PrivateConstructor{}, il, std::forward<Args>(args)...} {}
161 
162  // Used only when an Optional is used with coroutines on MSVC
164  : Optional{} {
165  p.promise_->value_ = this;
166  }
167 
168  void assign(const None&) {
169  clear();
170  }
171 
172  void assign(Optional&& src) {
173  if (this != &src) {
174  if (src.hasValue()) {
175  assign(std::move(src.value()));
176  src.clear();
177  } else {
178  clear();
179  }
180  }
181  }
182 
183  void assign(const Optional& src) {
184  if (src.hasValue()) {
185  assign(src.value());
186  } else {
187  clear();
188  }
189  }
190 
191  void assign(Value&& newValue) {
192  if (hasValue()) {
193  storage_.value = std::move(newValue);
194  } else {
195  construct(std::move(newValue));
196  }
197  }
198 
199  void assign(const Value& newValue) {
200  if (hasValue()) {
201  storage_.value = newValue;
202  } else {
203  construct(newValue);
204  }
205  }
206 
208  reset();
209  return *this;
210  }
211 
212  template <class Arg>
213  Optional& operator=(Arg&& arg) {
214  assign(std::forward<Arg>(arg));
215  return *this;
216  }
217 
219  std::is_nothrow_move_assignable<Value>::value) {
220  assign(std::move(other));
221  return *this;
222  }
223 
226  assign(other);
227  return *this;
228  }
229 
230  template <class... Args>
231  Value& emplace(Args&&... args) {
232  clear();
233  construct(std::forward<Args>(args)...);
234  return value();
235  }
236 
237  template <class U, class... Args>
238  typename std::enable_if<
239  std::is_constructible<Value, std::initializer_list<U>&, Args&&...>::value,
240  Value&>::type
241  emplace(std::initializer_list<U> ilist, Args&&... args) {
242  clear();
243  construct(ilist, std::forward<Args>(args)...);
244  return value();
245  }
246 
247  void reset() noexcept {
248  storage_.clear();
249  }
250 
251  void clear() noexcept {
252  reset();
253  }
254 
256  if (hasValue() && that.hasValue()) {
257  using std::swap;
258  swap(value(), that.value());
259  } else if (hasValue()) {
260  that.emplace(std::move(value()));
261  reset();
262  } else if (that.hasValue()) {
263  emplace(std::move(that.value()));
264  that.reset();
265  }
266  }
267 
269  require_value();
270  return storage_.value;
271  }
272 
274  require_value();
275  return storage_.value;
276  }
277 
279  require_value();
280  return std::move(storage_.value);
281  }
282 
284  require_value();
285  return std::move(storage_.value);
286  }
287 
288  const Value* get_pointer() const& {
289  return storage_.hasValue ? &storage_.value : nullptr;
290  }
292  return storage_.hasValue ? &storage_.value : nullptr;
293  }
294  Value* get_pointer() && = delete;
295 
297  return storage_.hasValue;
298  }
299 
301  return has_value();
302  }
303 
304  FOLLY_CPP14_CONSTEXPR explicit operator bool() const noexcept {
305  return has_value();
306  }
307 
309  return value();
310  }
312  return value();
313  }
315  return std::move(value());
316  }
318  return std::move(value());
319  }
320 
322  return &value();
323  }
325  return &value();
326  }
327 
328  // Return a copy of the value if set, or a given default if not.
329  template <class U>
331  if (storage_.hasValue) {
332  return storage_.value;
333  }
334 
335  return std::forward<U>(dflt);
336  }
337 
338  template <class U>
340  if (storage_.hasValue) {
341  return std::move(storage_.value);
342  }
343 
344  return std::forward<U>(dflt);
345  }
346 
347  private:
348  template <class T>
349  friend constexpr Optional<_t<std::decay<T>>> make_optional(T&&);
350  template <class T, class... Args>
351  friend constexpr Optional<T> make_optional(Args&&... args);
352  template <class T, class U, class... As>
353  friend constexpr Optional<T> make_optional(std::initializer_list<U>, As&&...);
354 
364  explicit PrivateConstructor() = default;
365  };
366  template <typename... Args>
367  FOLLY_CPP14_CONSTEXPR Optional(PrivateConstructor, Args&&... args) noexcept(
368  std::is_constructible<Value, Args&&...>::value) {
369  construct(std::forward<Args>(args)...);
370  }
371 
372  void require_value() const {
373  if (!storage_.hasValue) {
374  throw_exception<OptionalEmptyException>();
375  }
376  }
377 
378  template <class... Args>
379  void construct(Args&&... args) {
380  const void* ptr = &storage_.value;
381  // For supporting const types.
382  new (const_cast<void*>(ptr)) Value(std::forward<Args>(args)...);
383  storage_.hasValue = true;
384  }
385 
387  union {
390  };
391  bool hasValue;
392 
393  StorageTriviallyDestructible() : hasValue{false} {}
394  void clear() {
395  hasValue = false;
396  }
397  };
398 
400  union {
403  };
404  bool hasValue;
405 
407  // These are both informational warnings, but they trigger rare
408  // enough that we've left them enabled. Needed as long as MSVC
409  // 2015 is supported.
410  FOLLY_MSVC_DISABLE_WARNING(4587) // constructor of .value is not called
411  FOLLY_MSVC_DISABLE_WARNING(4588) // destructor of .value is not called
412  StorageNonTriviallyDestructible() : hasValue{false} {}
414  clear();
415  }
417 
418  void clear() {
419  if (hasValue) {
420  hasValue = false;
421  value.~Value();
422  }
423  }
424  };
425 
426  using Storage = typename std::conditional<
429  StorageNonTriviallyDestructible>::type;
430 
432 };
433 
434 template <class T>
435 const T* get_pointer(const Optional<T>& opt) {
436  return opt.get_pointer();
437 }
438 
439 template <class T>
441  return opt.get_pointer();
442 }
443 
444 template <class T>
446  a.swap(b);
447 }
448 
449 template <class T>
451  using PrivateConstructor =
452  typename folly::Optional<_t<std::decay<T>>>::PrivateConstructor;
453  return {PrivateConstructor{}, std::forward<T>(v)};
454 }
455 
456 template <class T, class... Args>
457 constexpr folly::Optional<T> make_optional(Args&&... args) {
458  using PrivateConstructor = typename folly::Optional<T>::PrivateConstructor;
459  return {PrivateConstructor{}, std::forward<Args>(args)...};
460 }
461 
462 template <class T, class U, class... Args>
464  std::initializer_list<U> il,
465  Args&&... args) {
466  using PrivateConstructor = typename folly::Optional<T>::PrivateConstructor;
467  return {PrivateConstructor{}, il, std::forward<Args>(args)...};
468 }
469 
471 // Comparisons.
472 
473 template <class U, class V>
474 constexpr bool operator==(const Optional<U>& a, const V& b) {
475  return a.hasValue() && a.value() == b;
476 }
477 
478 template <class U, class V>
479 constexpr bool operator!=(const Optional<U>& a, const V& b) {
480  return !(a == b);
481 }
482 
483 template <class U, class V>
484 constexpr bool operator==(const U& a, const Optional<V>& b) {
485  return b.hasValue() && b.value() == a;
486 }
487 
488 template <class U, class V>
489 constexpr bool operator!=(const U& a, const Optional<V>& b) {
490  return !(a == b);
491 }
492 
493 template <class U, class V>
495  const Optional<U>& a,
496  const Optional<V>& b) {
497  if (a.hasValue() != b.hasValue()) {
498  return false;
499  }
500  if (a.hasValue()) {
501  return a.value() == b.value();
502  }
503  return true;
504 }
505 
506 template <class U, class V>
507 constexpr bool operator!=(const Optional<U>& a, const Optional<V>& b) {
508  return !(a == b);
509 }
510 
511 template <class U, class V>
513  const Optional<U>& a,
514  const Optional<V>& b) {
515  if (a.hasValue() != b.hasValue()) {
516  return a.hasValue() < b.hasValue();
517  }
518  if (a.hasValue()) {
519  return a.value() < b.value();
520  }
521  return false;
522 }
523 
524 template <class U, class V>
525 constexpr bool operator>(const Optional<U>& a, const Optional<V>& b) {
526  return b < a;
527 }
528 
529 template <class U, class V>
530 constexpr bool operator<=(const Optional<U>& a, const Optional<V>& b) {
531  return !(b < a);
532 }
533 
534 template <class U, class V>
535 constexpr bool operator>=(const Optional<U>& a, const Optional<V>& b) {
536  return !(a < b);
537 }
538 
539 // Suppress comparability of Optional<T> with T, despite implicit conversion.
540 template <class V>
541 bool operator<(const Optional<V>&, const V& other) = delete;
542 template <class V>
543 bool operator<=(const Optional<V>&, const V& other) = delete;
544 template <class V>
545 bool operator>=(const Optional<V>&, const V& other) = delete;
546 template <class V>
547 bool operator>(const Optional<V>&, const V& other) = delete;
548 template <class V>
549 bool operator<(const V& other, const Optional<V>&) = delete;
550 template <class V>
551 bool operator<=(const V& other, const Optional<V>&) = delete;
552 template <class V>
553 bool operator>=(const V& other, const Optional<V>&) = delete;
554 template <class V>
555 bool operator>(const V& other, const Optional<V>&) = delete;
556 
557 // Comparisons with none
558 template <class V>
559 constexpr bool operator==(const Optional<V>& a, None) noexcept {
560  return !a.hasValue();
561 }
562 template <class V>
563 constexpr bool operator==(None, const Optional<V>& a) noexcept {
564  return !a.hasValue();
565 }
566 template <class V>
567 constexpr bool operator<(const Optional<V>&, None) noexcept {
568  return false;
569 }
570 template <class V>
571 constexpr bool operator<(None, const Optional<V>& a) noexcept {
572  return a.hasValue();
573 }
574 template <class V>
575 constexpr bool operator>(const Optional<V>& a, None) noexcept {
576  return a.hasValue();
577 }
578 template <class V>
579 constexpr bool operator>(None, const Optional<V>&) noexcept {
580  return false;
581 }
582 template <class V>
583 constexpr bool operator<=(None, const Optional<V>&) noexcept {
584  return true;
585 }
586 template <class V>
587 constexpr bool operator<=(const Optional<V>& a, None) noexcept {
588  return !a.hasValue();
589 }
590 template <class V>
591 constexpr bool operator>=(const Optional<V>&, None) noexcept {
592  return true;
593 }
594 template <class V>
595 constexpr bool operator>=(None, const Optional<V>& a) noexcept {
596  return !a.hasValue();
597 }
598 
600 
601 } // namespace folly
602 
603 // Allow usage of Optional<T> in std::unordered_map and std::unordered_set
605 template <class T>
606 struct hash<folly::Optional<T>> {
607  size_t operator()(folly::Optional<T> const& obj) const {
608  if (!obj.hasValue()) {
609  return 0;
610  }
611  return hash<typename remove_const<T>::type>()(*obj);
612  }
613 };
615 
616 // Enable the use of folly::Optional with `co_await`
617 // Inspired by https://github.com/toby-allsopp/coroutine_monad
618 #if FOLLY_HAS_COROUTINES
619 #include <experimental/coroutine>
620 
621 namespace folly {
622 namespace detail {
623 template <typename Value>
624 struct OptionalPromise;
625 
626 template <typename Value>
627 struct OptionalPromiseReturn {
628  Optional<Value> storage_;
629  OptionalPromise<Value>* promise_;
630  /* implicit */ OptionalPromiseReturn(OptionalPromise<Value>& promise) noexcept
631  : promise_(&promise) {
632  promise.value_ = &storage_;
633  }
634  OptionalPromiseReturn(OptionalPromiseReturn&& that) noexcept
635  : OptionalPromiseReturn{*that.promise_} {}
636  ~OptionalPromiseReturn() {}
637  /* implicit */ operator Optional<Value>() & {
638  return std::move(storage_);
639  }
640 };
641 
642 template <typename Value>
643 struct OptionalPromise {
644  Optional<Value>* value_ = nullptr;
645  OptionalPromise() = default;
646  OptionalPromise(OptionalPromise const&) = delete;
647  // This should work regardless of whether the compiler generates:
648  // folly::Optional<Value> retobj{ p.get_return_object(); } // MSVC
649  // or:
650  // auto retobj = p.get_return_object(); // clang
651  OptionalPromiseReturn<Value> get_return_object() noexcept {
652  return *this;
653  }
654  std::experimental::suspend_never initial_suspend() const noexcept {
655  return {};
656  }
657  std::experimental::suspend_never final_suspend() const {
658  return {};
659  }
660  template <typename U>
661  void return_value(U&& u) {
662  *value_ = static_cast<U&&>(u);
663  }
664  void unhandled_exception() {
665  // Technically, throwing from unhandled_exception is underspecified:
666  // https://github.com/GorNishanov/CoroutineWording/issues/17
667  throw;
668  }
669 };
670 
671 template <typename Value>
672 struct OptionalAwaitable {
673  Optional<Value> o_;
674  bool await_ready() const noexcept {
675  return o_.hasValue();
676  }
677  Value await_resume() {
678  return std::move(o_.value());
679  }
680 
681  // Explicitly only allow suspension into an OptionalPromise
682  template <typename U>
683  void await_suspend(
684  std::experimental::coroutine_handle<OptionalPromise<U>> h) const {
685  // Abort the rest of the coroutine. resume() is not going to be called
686  h.destroy();
687  }
688 };
689 } // namespace detail
690 
691 template <typename Value>
692 detail::OptionalAwaitable<Value>
693 /* implicit */ operator co_await(Optional<Value> o) {
694  return {std::move(o)};
695 }
696 } // namespace folly
697 
698 // This makes folly::Optional<Value> useable as a coroutine return type..
699 namespace std {
700 namespace experimental {
701 template <typename Value, typename... Args>
702 struct coroutine_traits<folly::Optional<Value>, Args...> {
703  using promise_type = folly::detail::OptionalPromise<Value>;
704 };
705 } // namespace experimental
706 } // namespace std
707 #endif // FOLLY_HAS_COROUTINES
FOLLY_CPP14_CONSTEXPR Value && value()&&
Definition: Optional.h:278
void * ptr
bool operator>(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1349
*than *hazptr_holder h
Definition: Hazptr.h:116
#define FOLLY_POP_WARNING
Definition: Portability.h:179
Optional(Optional &&src) noexcept(std::is_nothrow_move_constructible< Value >::value)
Definition: Optional.h:116
auto v
FOLLY_CPP14_CONSTEXPR Optional(Value &&newValue) noexcept(std::is_nothrow_move_constructible< Value >::value)
Definition: Optional.h:126
#define FOLLY_PUSH_WARNING
Definition: Portability.h:178
FOLLY_CPP14_CONSTEXPR Optional(in_place_t, std::initializer_list< U > il, Args &&...args) noexcept(std::is_nothrow_constructible< Value, std::initializer_list< U >, Args... >::value)
Definition: Optional.h:152
char b
FOLLY_CPP14_CONSTEXPR Value && operator*()&&
Definition: Optional.h:317
void construct(Args &&...args)
Definition: Optional.h:379
void assign(const Optional &src)
Definition: Optional.h:183
void assign(const None &)
Definition: Optional.h:168
PskType type
#define FOLLY_CPP14_CONSTEXPR
Definition: Portability.h:424
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Optional & operator=(Optional &&other) noexcept(std::is_nothrow_move_assignable< Value >::value)
Definition: Optional.h:218
STL namespace.
FOLLY_CPP14_CONSTEXPR const Value && operator*() const &&
Definition: Optional.h:314
FOLLY_CPP14_CONSTEXPR bool has_value() const noexcept
Definition: Optional.h:296
void assign(Value &&newValue)
Definition: Optional.h:191
void swap(Optional &that) noexcept(IsNothrowSwappable< Value >::value)
Definition: Optional.h:255
folly::std T
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define FOLLY_EXPORT
Definition: CPortability.h:133
requires E e noexcept(noexcept(s.error(std::move(e))))
Value value_type
Definition: Optional.h:98
in_place_tag(&)(in_place_tag) in_place_t
Definition: Utility.h:229
void assign(const Value &newValue)
Definition: Optional.h:199
FOLLY_CPP14_CONSTEXPR Value * operator->()
Definition: Optional.h:324
constexpr Optional< _t< std::decay< T > > > make_optional(T &&v)
Definition: Optional.h:450
bool operator!=(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
Definition: Expected.h:766
FOLLY_PUSH_WARNING FOLLY_MSVC_DISABLE_WARNING(4388) FOLLY_MSVC_DISABLE_WARNING(4804) template< typename RHS
FOLLY_CPP14_CONSTEXPR Optional() noexcept
Definition: Optional.h:107
const Value * get_pointer() const &
Definition: Optional.h:288
constexpr None(_secret)
Definition: Optional.h:85
#define FOLLY_NAMESPACE_STD_BEGIN
Definition: Portability.h:226
FOLLY_CPP14_CONSTEXPR Optional(const None &) noexcept
Definition: Optional.h:124
FOLLY_CPP14_CONSTEXPR const Value & operator*() const &
Definition: Optional.h:308
size_t operator()(folly::Optional< T > const &obj) const
Definition: Optional.h:607
FOLLY_PUSH_WARNING FOLLY_MSVC_DISABLE_WARNING(4587) FOLLY_MSVC_DISABLE_WARNING(4588) StorageNonTriviallyDestructible()
Definition: Optional.h:410
bool Value(const T &value, M matcher)
typename std::conditional< std::is_trivially_destructible< Value >::value, StorageTriviallyDestructible, StorageNonTriviallyDestructible >::type Storage
Definition: Optional.h:429
FOLLY_CPP14_CONSTEXPR bool hasValue() const noexcept
Definition: Optional.h:300
Promise< Unit > promise_
void require_value() const
Definition: Optional.h:372
char a
FOLLY_CPP14_CONSTEXPR Optional(PrivateConstructor, Args &&...args) noexcept(std::is_constructible< Value, Args &&... >::value)
Definition: Optional.h:367
static const char *const value
Definition: Conv.cpp:50
Value & emplace(Args &&...args)
Definition: Optional.h:231
Optional & operator=(None) noexcept
Definition: Optional.h:207
Optional(const Optional &src) noexcept(std::is_nothrow_copy_constructible< Value >::value)
Definition: Optional.h:109
FOLLY_CPP14_CONSTEXPR Value value_or(U &&dflt)&&
Definition: Optional.h:339
FOLLY_CPP14_CONSTEXPR Value value_or(U &&dflt) const &
Definition: Optional.h:330
void assign(Optional &&src)
Definition: Optional.h:172
Optional & operator=(Arg &&arg)
Definition: Optional.h:213
bool operator>=(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1358
FOLLY_CPP14_CONSTEXPR Value & operator*()&
Definition: Optional.h:311
const Value * get_pointer(const Expected< Value, Error > &ex) noexcept
Definition: Expected.h:1374
void swap(exception_wrapper &a, exception_wrapper &b) noexcept
std::enable_if< std::is_constructible< Value, std::initializer_list< U > &, Args &&... >::value, Value & >::type emplace(std::initializer_list< U > ilist, Args &&...args)
Definition: Optional.h:241
void reset() noexcept
Definition: Optional.h:247
FOLLY_CPP14_CONSTEXPR const Value && value() const &&
Definition: Optional.h:283
bool operator==(const Unexpected< Error > &lhs, const Unexpected< Error > &rhs)
Definition: Expected.h:758
Optional(const detail::OptionalPromiseReturn< Value > &p)
Definition: Optional.h:163
const
Definition: upload.py:398
Storage storage_
Definition: Optional.h:431
FOLLY_CPP14_CONSTEXPR Optional(const Value &newValue) noexcept(std::is_nothrow_copy_constructible< Value >::value)
Definition: Optional.h:131
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
FOLLY_CPP14_CONSTEXPR Optional(typename std::enable_if< !std::is_pointer< Value >::value &&std::is_same< Null, std::nullptr_t >::value, Null >::type) noexcept
Definition: Optional.h:141
FOLLY_CPP14_CONSTEXPR Value & value()&
Definition: Optional.h:273
FOLLY_CPP14_CONSTEXPR const Value & value() const &
Definition: Optional.h:268
Value * get_pointer()&
Definition: Optional.h:291
void swap(Optional< T > &a, Optional< T > &b) noexcept(noexcept(a.swap(b)))
Definition: Optional.h:445
FOLLY_CPP14_CONSTEXPR const Value * operator->() const
Definition: Optional.h:321
std::enable_if< IsLessThanComparable< Value >::value, bool >::type operator<(const Expected< Value, Error > &lhs, const Expected< Value, Error > &rhs)
Definition: Expected.h:1321
constexpr None none
Definition: Optional.h:87
#define FOLLY_NAMESPACE_STD_END
Definition: Portability.h:227
FOLLY_CPP14_CONSTEXPR Optional(in_place_t, Args &&...args) noexcept(std::is_nothrow_constructible< Value, Args... >::value)
Definition: Optional.h:147
void clear() noexcept
Definition: Optional.h:251
Optional & operator=(const Optional &other) noexcept(std::is_nothrow_copy_assignable< Value >::value)
Definition: Optional.h:224