Optional.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  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. * Optional - For conditional initialization of values, like boost::optional,
  19. * but with support for move semantics and emplacement. Reference type support
  20. * has not been included due to limited use cases and potential confusion with
  21. * semantics of assignment: Assigning to an optional reference could quite
  22. * reasonably copy its value or redirect the reference.
  23. *
  24. * Optional can be useful when a variable might or might not be needed:
  25. *
  26. * Optional<Logger> maybeLogger = ...;
  27. * if (maybeLogger) {
  28. * maybeLogger->log("hello");
  29. * }
  30. *
  31. * Optional enables a 'null' value for types which do not otherwise have
  32. * nullability, especially useful for parameter passing:
  33. *
  34. * void testIterator(const unique_ptr<Iterator>& it,
  35. * initializer_list<int> idsExpected,
  36. * Optional<initializer_list<int>> ranksExpected = none) {
  37. * for (int i = 0; it->next(); ++i) {
  38. * EXPECT_EQ(it->doc().id(), idsExpected[i]);
  39. * if (ranksExpected) {
  40. * EXPECT_EQ(it->doc().rank(), (*ranksExpected)[i]);
  41. * }
  42. * }
  43. * }
  44. *
  45. * Optional models OptionalPointee, so calling 'get_pointer(opt)' will return a
  46. * pointer to nullptr if the 'opt' is empty, and a pointer to the value if it is
  47. * not:
  48. *
  49. * Optional<int> maybeInt = ...;
  50. * if (int* v = get_pointer(maybeInt)) {
  51. * cout << *v << endl;
  52. * }
  53. */
  54. #include <cstddef>
  55. #include <functional>
  56. #include <new>
  57. #include <stdexcept>
  58. #include <type_traits>
  59. #include <utility>
  60. #include <folly/Portability.h>
  61. #include <folly/Traits.h>
  62. #include <folly/Utility.h>
  63. #include <folly/lang/Exception.h>
  64. namespace folly {
  65. template <class Value>
  66. class Optional;
  67. namespace detail {
  68. struct NoneHelper {};
  69. template <class Value>
  70. struct OptionalPromiseReturn;
  71. } // namespace detail
  72. typedef int detail::NoneHelper::*None;
  73. const None none = {};
  74. class FOLLY_EXPORT OptionalEmptyException : public std::runtime_error {
  75. public:
  76. OptionalEmptyException()
  77. : std::runtime_error("Empty Optional cannot be unwrapped") {}
  78. };
  79. template <class Value>
  80. class Optional {
  81. public:
  82. typedef Value value_type;
  83. static_assert(
  84. !std::is_reference<Value>::value,
  85. "Optional may not be used with reference types");
  86. static_assert(
  87. !std::is_abstract<Value>::value,
  88. "Optional may not be used with abstract types");
  89. FOLLY_CPP14_CONSTEXPR Optional() noexcept {}
  90. Optional(const Optional& src) noexcept(
  91. std::is_nothrow_copy_constructible<Value>::value) {
  92. if (src.hasValue()) {
  93. construct(src.value());
  94. }
  95. }
  96. Optional(Optional&& src) noexcept(
  97. std::is_nothrow_move_constructible<Value>::value) {
  98. if (src.hasValue()) {
  99. construct(std::move(src.value()));
  100. src.clear();
  101. }
  102. }
  103. FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(const None&) noexcept {}
  104. FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(Value&& newValue) noexcept(
  105. std::is_nothrow_move_constructible<Value>::value) {
  106. construct(std::move(newValue));
  107. }
  108. FOLLY_CPP14_CONSTEXPR /* implicit */ Optional(const Value& newValue) noexcept(
  109. std::is_nothrow_copy_constructible<Value>::value) {
  110. construct(newValue);
  111. }
  112. template <typename... Args>
  113. FOLLY_CPP14_CONSTEXPR explicit Optional(in_place_t, Args&&... args) noexcept(
  114. std::is_nothrow_constructible<Value, Args...>::value) {
  115. construct(std::forward<Args>(args)...);
  116. }
  117. // Used only when an Optional is used with coroutines on MSVC
  118. /* implicit */ Optional(const detail::OptionalPromiseReturn<Value>& p)
  119. : Optional{} {
  120. p.promise_->value_ = this;
  121. }
  122. void assign(const None&) {
  123. clear();
  124. }
  125. void assign(Optional&& src) {
  126. if (this != &src) {
  127. if (src.hasValue()) {
  128. assign(std::move(src.value()));
  129. src.clear();
  130. } else {
  131. clear();
  132. }
  133. }
  134. }
  135. void assign(const Optional& src) {
  136. if (src.hasValue()) {
  137. assign(src.value());
  138. } else {
  139. clear();
  140. }
  141. }
  142. void assign(Value&& newValue) {
  143. if (hasValue()) {
  144. storage_.value = std::move(newValue);
  145. } else {
  146. construct(std::move(newValue));
  147. }
  148. }
  149. void assign(const Value& newValue) {
  150. if (hasValue()) {
  151. storage_.value = newValue;
  152. } else {
  153. construct(newValue);
  154. }
  155. }
  156. template <class Arg>
  157. Optional& operator=(Arg&& arg) {
  158. assign(std::forward<Arg>(arg));
  159. return *this;
  160. }
  161. Optional& operator=(Optional&& other) noexcept(
  162. std::is_nothrow_move_assignable<Value>::value) {
  163. assign(std::move(other));
  164. return *this;
  165. }
  166. Optional& operator=(const Optional& other) noexcept(
  167. std::is_nothrow_copy_assignable<Value>::value) {
  168. assign(other);
  169. return *this;
  170. }
  171. template <class... Args>
  172. Value& emplace(Args&&... args) {
  173. clear();
  174. construct(std::forward<Args>(args)...);
  175. return value();
  176. }
  177. template <class U, class... Args>
  178. typename std::enable_if<
  179. std::is_constructible<Value, std::initializer_list<U>&, Args&&...>::value,
  180. Value&>::type
  181. emplace(std::initializer_list<U> ilist, Args&&... args) {
  182. clear();
  183. construct(ilist, std::forward<Args>(args)...);
  184. return value();
  185. }
  186. void reset() noexcept {
  187. storage_.clear();
  188. }
  189. void clear() noexcept {
  190. reset();
  191. }
  192. void swap(Optional& that) noexcept(IsNothrowSwappable<Value>::value) {
  193. if (hasValue() && that.hasValue()) {
  194. using std::swap;
  195. swap(value(), that.value());
  196. } else if (hasValue()) {
  197. that.emplace(std::move(value()));
  198. reset();
  199. } else if (that.hasValue()) {
  200. emplace(std::move(that.value()));
  201. that.reset();
  202. }
  203. }
  204. FOLLY_CPP14_CONSTEXPR const Value& value() const& {
  205. require_value();
  206. return storage_.value;
  207. }
  208. FOLLY_CPP14_CONSTEXPR Value& value() & {
  209. require_value();
  210. return storage_.value;
  211. }
  212. FOLLY_CPP14_CONSTEXPR Value&& value() && {
  213. require_value();
  214. return std::move(storage_.value);
  215. }
  216. FOLLY_CPP14_CONSTEXPR const Value&& value() const&& {
  217. require_value();
  218. return std::move(storage_.value);
  219. }
  220. const Value* get_pointer() const& {
  221. return storage_.hasValue ? &storage_.value : nullptr;
  222. }
  223. Value* get_pointer() & {
  224. return storage_.hasValue ? &storage_.value : nullptr;
  225. }
  226. Value* get_pointer() && = delete;
  227. FOLLY_CPP14_CONSTEXPR bool has_value() const noexcept {
  228. return storage_.hasValue;
  229. }
  230. FOLLY_CPP14_CONSTEXPR bool hasValue() const noexcept {
  231. return has_value();
  232. }
  233. FOLLY_CPP14_CONSTEXPR explicit operator bool() const noexcept {
  234. return has_value();
  235. }
  236. FOLLY_CPP14_CONSTEXPR const Value& operator*() const& {
  237. return value();
  238. }
  239. FOLLY_CPP14_CONSTEXPR Value& operator*() & {
  240. return value();
  241. }
  242. FOLLY_CPP14_CONSTEXPR const Value&& operator*() const&& {
  243. return std::move(value());
  244. }
  245. FOLLY_CPP14_CONSTEXPR Value&& operator*() && {
  246. return std::move(value());
  247. }
  248. FOLLY_CPP14_CONSTEXPR const Value* operator->() const {
  249. return &value();
  250. }
  251. FOLLY_CPP14_CONSTEXPR Value* operator->() {
  252. return &value();
  253. }
  254. // Return a copy of the value if set, or a given default if not.
  255. template <class U>
  256. FOLLY_CPP14_CONSTEXPR Value value_or(U&& dflt) const& {
  257. if (storage_.hasValue) {
  258. return storage_.value;
  259. }
  260. return std::forward<U>(dflt);
  261. }
  262. template <class U>
  263. FOLLY_CPP14_CONSTEXPR Value value_or(U&& dflt) && {
  264. if (storage_.hasValue) {
  265. return std::move(storage_.value);
  266. }
  267. return std::forward<U>(dflt);
  268. }
  269. private:
  270. void require_value() const {
  271. if (!storage_.hasValue) {
  272. throw_exception<OptionalEmptyException>();
  273. }
  274. }
  275. template <class... Args>
  276. void construct(Args&&... args) {
  277. const void* ptr = &storage_.value;
  278. // For supporting const types.
  279. new (const_cast<void*>(ptr)) Value(std::forward<Args>(args)...);
  280. storage_.hasValue = true;
  281. }
  282. struct StorageTriviallyDestructible {
  283. union {
  284. char emptyState;
  285. Value value;
  286. };
  287. bool hasValue;
  288. StorageTriviallyDestructible() : hasValue{false} {}
  289. void clear() {
  290. hasValue = false;
  291. }
  292. };
  293. struct StorageNonTriviallyDestructible {
  294. union {
  295. char emptyState;
  296. Value value;
  297. };
  298. bool hasValue;
  299. FOLLY_PUSH_WARNING
  300. // These are both informational warnings, but they trigger rare
  301. // enough that we've left them enabled. Needed as long as MSVC
  302. // 2015 is supported.
  303. FOLLY_MSVC_DISABLE_WARNING(4587) // constructor of .value is not called
  304. FOLLY_MSVC_DISABLE_WARNING(4588) // destructor of .value is not called
  305. StorageNonTriviallyDestructible() : hasValue{false} {}
  306. ~StorageNonTriviallyDestructible() {
  307. clear();
  308. }
  309. FOLLY_POP_WARNING
  310. void clear() {
  311. if (hasValue) {
  312. hasValue = false;
  313. value.~Value();
  314. }
  315. }
  316. };
  317. using Storage = typename std::conditional<
  318. std::is_trivially_destructible<Value>::value,
  319. StorageTriviallyDestructible,
  320. StorageNonTriviallyDestructible>::type;
  321. Storage storage_;
  322. };
  323. template <class T>
  324. const T* get_pointer(const Optional<T>& opt) {
  325. return opt.get_pointer();
  326. }
  327. template <class T>
  328. T* get_pointer(Optional<T>& opt) {
  329. return opt.get_pointer();
  330. }
  331. template <class T>
  332. void swap(Optional<T>& a, Optional<T>& b) noexcept(noexcept(a.swap(b))) {
  333. a.swap(b);
  334. }
  335. template <class T, class Opt = Optional<typename std::decay<T>::type>>
  336. constexpr Opt make_optional(T&& v) {
  337. return Opt(std::forward<T>(v));
  338. }
  339. ///////////////////////////////////////////////////////////////////////////////
  340. // Comparisons.
  341. template <class U, class V>
  342. constexpr bool operator==(const Optional<U>& a, const V& b) {
  343. return a.hasValue() && a.value() == b;
  344. }
  345. template <class U, class V>
  346. constexpr bool operator!=(const Optional<U>& a, const V& b) {
  347. return !(a == b);
  348. }
  349. template <class U, class V>
  350. constexpr bool operator==(const U& a, const Optional<V>& b) {
  351. return b.hasValue() && b.value() == a;
  352. }
  353. template <class U, class V>
  354. constexpr bool operator!=(const U& a, const Optional<V>& b) {
  355. return !(a == b);
  356. }
  357. template <class U, class V>
  358. FOLLY_CPP14_CONSTEXPR bool operator==(
  359. const Optional<U>& a,
  360. const Optional<V>& b) {
  361. if (a.hasValue() != b.hasValue()) {
  362. return false;
  363. }
  364. if (a.hasValue()) {
  365. return a.value() == b.value();
  366. }
  367. return true;
  368. }
  369. template <class U, class V>
  370. constexpr bool operator!=(const Optional<U>& a, const Optional<V>& b) {
  371. return !(a == b);
  372. }
  373. template <class U, class V>
  374. FOLLY_CPP14_CONSTEXPR bool operator<(
  375. const Optional<U>& a,
  376. const Optional<V>& b) {
  377. if (a.hasValue() != b.hasValue()) {
  378. return a.hasValue() < b.hasValue();
  379. }
  380. if (a.hasValue()) {
  381. return a.value() < b.value();
  382. }
  383. return false;
  384. }
  385. template <class U, class V>
  386. constexpr bool operator>(const Optional<U>& a, const Optional<V>& b) {
  387. return b < a;
  388. }
  389. template <class U, class V>
  390. constexpr bool operator<=(const Optional<U>& a, const Optional<V>& b) {
  391. return !(b < a);
  392. }
  393. template <class U, class V>
  394. constexpr bool operator>=(const Optional<U>& a, const Optional<V>& b) {
  395. return !(a < b);
  396. }
  397. // Suppress comparability of Optional<T> with T, despite implicit conversion.
  398. template <class V>
  399. bool operator<(const Optional<V>&, const V& other) = delete;
  400. template <class V>
  401. bool operator<=(const Optional<V>&, const V& other) = delete;
  402. template <class V>
  403. bool operator>=(const Optional<V>&, const V& other) = delete;
  404. template <class V>
  405. bool operator>(const Optional<V>&, const V& other) = delete;
  406. template <class V>
  407. bool operator<(const V& other, const Optional<V>&) = delete;
  408. template <class V>
  409. bool operator<=(const V& other, const Optional<V>&) = delete;
  410. template <class V>
  411. bool operator>=(const V& other, const Optional<V>&) = delete;
  412. template <class V>
  413. bool operator>(const V& other, const Optional<V>&) = delete;
  414. // Comparisons with none
  415. template <class V>
  416. constexpr bool operator==(const Optional<V>& a, None) noexcept {
  417. return !a.hasValue();
  418. }
  419. template <class V>
  420. constexpr bool operator==(None, const Optional<V>& a) noexcept {
  421. return !a.hasValue();
  422. }
  423. template <class V>
  424. constexpr bool operator<(const Optional<V>&, None) noexcept {
  425. return false;
  426. }
  427. template <class V>
  428. constexpr bool operator<(None, const Optional<V>& a) noexcept {
  429. return a.hasValue();
  430. }
  431. template <class V>
  432. constexpr bool operator>(const Optional<V>& a, None) noexcept {
  433. return a.hasValue();
  434. }
  435. template <class V>
  436. constexpr bool operator>(None, const Optional<V>&) noexcept {
  437. return false;
  438. }
  439. template <class V>
  440. constexpr bool operator<=(None, const Optional<V>&) noexcept {
  441. return true;
  442. }
  443. template <class V>
  444. constexpr bool operator<=(const Optional<V>& a, None) noexcept {
  445. return !a.hasValue();
  446. }
  447. template <class V>
  448. constexpr bool operator>=(const Optional<V>&, None) noexcept {
  449. return true;
  450. }
  451. template <class V>
  452. constexpr bool operator>=(None, const Optional<V>& a) noexcept {
  453. return !a.hasValue();
  454. }
  455. ///////////////////////////////////////////////////////////////////////////////
  456. } // namespace folly
  457. // Allow usage of Optional<T> in std::unordered_map and std::unordered_set
  458. FOLLY_NAMESPACE_STD_BEGIN
  459. template <class T>
  460. struct hash<folly::Optional<T>> {
  461. size_t operator()(folly::Optional<T> const& obj) const {
  462. if (!obj.hasValue()) {
  463. return 0;
  464. }
  465. return hash<typename remove_const<T>::type>()(*obj);
  466. }
  467. };
  468. FOLLY_NAMESPACE_STD_END
  469. // Enable the use of folly::Optional with `co_await`
  470. // Inspired by https://github.com/toby-allsopp/coroutine_monad
  471. #if FOLLY_HAS_COROUTINES
  472. #include <experimental/coroutine>
  473. namespace folly {
  474. namespace detail {
  475. template <typename Value>
  476. struct OptionalPromise;
  477. template <typename Value>
  478. struct OptionalPromiseReturn {
  479. Optional<Value> storage_;
  480. OptionalPromise<Value>* promise_;
  481. /* implicit */ OptionalPromiseReturn(OptionalPromise<Value>& promise) noexcept
  482. : promise_(&promise) {
  483. promise.value_ = &storage_;
  484. }
  485. OptionalPromiseReturn(OptionalPromiseReturn&& that) noexcept
  486. : OptionalPromiseReturn{*that.promise_} {}
  487. ~OptionalPromiseReturn() {}
  488. /* implicit */ operator Optional<Value>() & {
  489. return std::move(storage_);
  490. }
  491. };
  492. template <typename Value>
  493. struct OptionalPromise {
  494. Optional<Value>* value_ = nullptr;
  495. OptionalPromise() = default;
  496. OptionalPromise(OptionalPromise const&) = delete;
  497. // This should work regardless of whether the compiler generates:
  498. // folly::Optional<Value> retobj{ p.get_return_object(); } // MSVC
  499. // or:
  500. // auto retobj = p.get_return_object(); // clang
  501. OptionalPromiseReturn<Value> get_return_object() noexcept {
  502. return *this;
  503. }
  504. std::experimental::suspend_never initial_suspend() const noexcept {
  505. return {};
  506. }
  507. std::experimental::suspend_never final_suspend() const {
  508. return {};
  509. }
  510. template <typename U>
  511. void return_value(U&& u) {
  512. *value_ = static_cast<U&&>(u);
  513. }
  514. void unhandled_exception() {
  515. // Technically, throwing from unhandled_exception is underspecified:
  516. // https://github.com/GorNishanov/CoroutineWording/issues/17
  517. throw;
  518. }
  519. };
  520. template <typename Value>
  521. struct OptionalAwaitable {
  522. Optional<Value> o_;
  523. bool await_ready() const noexcept {
  524. return o_.hasValue();
  525. }
  526. Value await_resume() {
  527. return std::move(o_.value());
  528. }
  529. // Explicitly only allow suspension into an OptionalPromise
  530. template <typename U>
  531. void await_suspend(
  532. std::experimental::coroutine_handle<OptionalPromise<U>> h) const {
  533. // Abort the rest of the coroutine. resume() is not going to be called
  534. h.destroy();
  535. }
  536. };
  537. } // namespace detail
  538. template <typename Value>
  539. detail::OptionalAwaitable<Value>
  540. /* implicit */ operator co_await(Optional<Value> o) {
  541. return {std::move(o)};
  542. }
  543. } // namespace folly
  544. // This makes folly::Optional<Value> useable as a coroutine return type..
  545. namespace std {
  546. namespace experimental {
  547. template <typename Value, typename... Args>
  548. struct coroutine_traits<folly::Optional<Value>, Args...> {
  549. using promise_type = folly::detail::OptionalPromise<Value>;
  550. };
  551. } // namespace experimental
  552. } // namespace std
  553. #endif // FOLLY_HAS_COROUTINES