Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Unified Diff: base/optional.h

Issue 1245163002: Base: add Optional<T>. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/base.gypi ('k') | base/optional_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/optional.h
diff --git a/base/optional.h b/base/optional.h
new file mode 100644
index 0000000000000000000000000000000000000000..c0b2a0c61c90f5a59c9dc541211dee3fb15e5cc2
--- /dev/null
+++ b/base/optional.h
@@ -0,0 +1,151 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_OPTIONAL_H_
+#define BASE_OPTIONAL_H_
+
+#include "base/logging.h"
+#include "base/memory/aligned_memory.h"
+
+namespace base {
+
+// Specification:
+// http://en.cppreference.com/w/cpp/experimental/optional/nullopt_t
+struct nullopt_t {
+ explicit nullopt_t(int _) { }
danakj 2015/11/19 20:55:46 i recently discovered the style guide now says you
mlamouri (slow - plz ping) 2016/02/29 22:31:27 Done.
+};
+
+// Specification:
+// http://en.cppreference.com/w/cpp/experimental/optional/nullopt
+const nullopt_t nullopt(0);
+
+// base::Optional is a Chromium version of the C++ library experimental optional
+// class: http://en.cppreference.com/w/cpp/experimental/optional/optional
+// The following methods are not implemented:
+// - All methods using rvalue reference (ie. && operator).
danakj 2015/11/19 20:55:46 I think that I'd like to wait on this until we all
mlamouri (slow - plz ping) 2016/02/29 22:31:26 Kind of. I've updated the list. Let me know how th
+// Thus, instead of operator=(U&&), operator=(const T&) is implemented.
+// - Two constructor forms are not implemented.
+// - swap() and emplace() are not implemented.
+// - Private member |val| is not implemented.
+// - Some non-member functions, classes and helper objects are implemented but
+// not all.
+template <typename T>
+class Optional {
+ public:
+ Optional() : is_null_(true) { }
+ Optional(base::nullopt_t opt) : Optional() { }
+
+ Optional(const Optional& other)
danakj 2015/12/10 23:45:45 Can you add a Optional(Optional&&) constructor?
mlamouri (slow - plz ping) 2016/02/29 22:31:26 Done.
+ : Optional() {
+ if (!other.is_null_)
+ init(other.value());
+ }
+
+ Optional(const T& value)
danakj 2015/12/10 23:45:46 And an Optional(T&&) constructor
mlamouri (slow - plz ping) 2016/02/29 22:31:27 Done.
+ : Optional() {
+ init(value);
+ }
+
+ // The difference between the specification and this method is that this
+ // implementation doesn't use std::is_trivially_destructible.
mlamouri (slow - plz ping) 2016/02/29 22:31:27 Is it okay to use std::is_trivially_destructible?
+ ~Optional() {
+ free_if_needed();
+ }
+
+ Optional& operator=(base::nullopt_t opt) {
+ free_if_needed();
+ return *this;
+ }
+
+ Optional& operator=(const Optional& other) {
danakj 2015/12/10 23:45:45 can you add operator=(Optional&&)
mlamouri (slow - plz ping) 2016/02/29 22:31:26 Done.
+ if (other.is_null_) {
+ free_if_needed();
+ return *this;
+ }
+
+ init_or_assign(other.value());
+ return *this;
+ }
+
+ // This method is not part of the current C++ standard. It is instead defined
+ // as:
+ // template <class U>
+ // optional& operator=(U&& value);
+ Optional& operator=(const T& value) {
danakj 2015/12/10 23:45:45 Let's make this take a T&&
mlamouri (slow - plz ping) 2016/02/29 22:31:26 Done. I've included the per-spec std::enable_if.
+ init_or_assign(value);
+ return *this;
+ }
+
+ const T* operator->() const {
+ DCHECK(!is_null_);
+ return buffer_.template data_as<T>();
+ }
+
+ T* operator->() {
+ DCHECK(!is_null_);
+ return buffer_.template data_as<T>();
+ }
+
+ const T& operator*() const {
+ return value();
+ }
+
+ T& operator*() {
+ return value();
+ }
+
+ explicit operator bool() const { return !is_null_; }
danakj 2015/12/10 23:45:46 explicit operator is banned: http://chromium-cpp.a
mlamouri (slow - plz ping) 2016/02/29 22:31:26 I couldn't get that to work. The issue is that I c
+
+ T& value() {
danakj 2015/12/10 23:45:45 can you ref-quality this with &
mlamouri (slow - plz ping) 2016/02/29 22:31:27 Done.
+ DCHECK(!is_null_);
+ return *buffer_.template data_as<T>();
+ }
+
+ const T& value() const {
danakj 2015/12/10 23:45:45 and this with &, and add the T&& versions of valu
mlamouri (slow - plz ping) 2016/02/29 22:31:26 Done.
+ DCHECK(!is_null_);
+ return *buffer_.template data_as<T>();
+ }
+
+ template <class U>
+ T value_or(U&& default_value) const {
danakj 2015/12/10 23:45:46 can add the non-const version of this method too
mlamouri (slow - plz ping) 2016/02/29 22:31:26 Done.
+ return is_null_ ? default_value : value();
+ }
+
+ bool operator==(const Optional& other) const {
+ return (is_null_ && other.is_null_) ||
+ (!is_null_ && !other.is_null_ && value() == other.value());
+ }
+
+ bool operator!=(const Optional& other) const {
+ return !this->operator==(other);
+ }
+
+ private:
+ void init(const T& value) {
+ DCHECK(is_null_);
+ new (buffer_.template data_as<T>()) T(value);
+ is_null_ = false;
+ }
+
+ void init_or_assign(const T& value) {
+ if (is_null_)
+ init(value);
+ else
+ *buffer_.template data_as<T>() = value;
+ }
+
+ void free_if_needed() {
+ if (is_null_)
+ return;
+ buffer_.template data_as<T>()->~T();
+ is_null_ = true;
+ }
+
+ bool is_null_;
+ base::AlignedMemory<sizeof(T), ALIGNOF(T)> buffer_;
+};
+
+} // namespace base
+
+#endif // BASE_OPTIONAL_H_
« no previous file with comments | « base/base.gypi ('k') | base/optional_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698