/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* }
*/
#include <cstddef>
+#include <functional>
#include <new>
#include <stdexcept>
#include <type_traits>
#include <utility>
+#include <folly/Portability.h>
+
namespace folly {
-namespace detail { struct NoneHelper {}; }
+namespace detail {
+struct NoneHelper {};
+
+// Allow each translation unit to control its own -fexceptions setting.
+// If exceptions are disabled, std::terminate() will be called instead of
+// throwing OptionalEmptyException when the condition fails.
+[[noreturn]] void throw_optional_empty_exception();
+}
typedef int detail::NoneHelper::*None;
private:
void require_value() const {
if (!storage_.hasValue) {
- throw OptionalEmptyException();
+ detail::throw_optional_empty_exception();
}
}
struct StorageTriviallyDestructible {
// The union trick allows to initialize the Optional's memory,
- // so that compiler/tools don't complain about unitialized memory,
+ // so that compiler/tools don't complain about uninitialized memory,
// without actually calling Value's default constructor.
// The rest of the implementation enforces that hasValue/value are
// synchronized.
};
};
+ FOLLY_PUSH_WARNING
+ // These are both informational warnings, but they trigger rare enough
+ // that we've left them enabled.
+ FOLLY_MSVC_DISABLE_WARNING(4587) // constructor of .value is not called
+ FOLLY_MSVC_DISABLE_WARNING(4588) // destructor of .value is not called
StorageNonTriviallyDestructible() : hasValue{false} {}
~StorageNonTriviallyDestructible() {
clear();
}
+ FOLLY_POP_WARNING
void clear() {
if (hasValue) {
///////////////////////////////////////////////////////////////////////////////
} // namespace folly
+
+// Allow usage of Optional<T> in std::unordered_map and std::unordered_set
+FOLLY_NAMESPACE_STD_BEGIN
+template <class T>
+struct hash<folly::Optional<T>> {
+ size_t operator()(folly::Optional<T> const& obj) const {
+ if (!obj.hasValue()) {
+ return 0;
+ }
+ return hash<typename remove_const<T>::type>()(*obj);
+ }
+};
+FOLLY_NAMESPACE_STD_END