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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « base/base.gypi ('k') | base/optional_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef BASE_OPTIONAL_H_
6 #define BASE_OPTIONAL_H_
7
8 #include "base/logging.h"
9 #include "base/memory/aligned_memory.h"
10
11 namespace base {
12
13 // Specification:
14 // http://en.cppreference.com/w/cpp/experimental/optional/nullopt_t
15 struct nullopt_t {
16 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.
17 };
18
19 // Specification:
20 // http://en.cppreference.com/w/cpp/experimental/optional/nullopt
21 const nullopt_t nullopt(0);
22
23 // base::Optional is a Chromium version of the C++ library experimental optional
24 // class: http://en.cppreference.com/w/cpp/experimental/optional/optional
25 // The following methods are not implemented:
26 // - 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
27 // Thus, instead of operator=(U&&), operator=(const T&) is implemented.
28 // - Two constructor forms are not implemented.
29 // - swap() and emplace() are not implemented.
30 // - Private member |val| is not implemented.
31 // - Some non-member functions, classes and helper objects are implemented but
32 // not all.
33 template <typename T>
34 class Optional {
35 public:
36 Optional() : is_null_(true) { }
37 Optional(base::nullopt_t opt) : Optional() { }
38
39 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.
40 : Optional() {
41 if (!other.is_null_)
42 init(other.value());
43 }
44
45 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.
46 : Optional() {
47 init(value);
48 }
49
50 // The difference between the specification and this method is that this
51 // 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?
52 ~Optional() {
53 free_if_needed();
54 }
55
56 Optional& operator=(base::nullopt_t opt) {
57 free_if_needed();
58 return *this;
59 }
60
61 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.
62 if (other.is_null_) {
63 free_if_needed();
64 return *this;
65 }
66
67 init_or_assign(other.value());
68 return *this;
69 }
70
71 // This method is not part of the current C++ standard. It is instead defined
72 // as:
73 // template <class U>
74 // optional& operator=(U&& value);
75 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.
76 init_or_assign(value);
77 return *this;
78 }
79
80 const T* operator->() const {
81 DCHECK(!is_null_);
82 return buffer_.template data_as<T>();
83 }
84
85 T* operator->() {
86 DCHECK(!is_null_);
87 return buffer_.template data_as<T>();
88 }
89
90 const T& operator*() const {
91 return value();
92 }
93
94 T& operator*() {
95 return value();
96 }
97
98 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
99
100 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.
101 DCHECK(!is_null_);
102 return *buffer_.template data_as<T>();
103 }
104
105 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.
106 DCHECK(!is_null_);
107 return *buffer_.template data_as<T>();
108 }
109
110 template <class U>
111 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.
112 return is_null_ ? default_value : value();
113 }
114
115 bool operator==(const Optional& other) const {
116 return (is_null_ && other.is_null_) ||
117 (!is_null_ && !other.is_null_ && value() == other.value());
118 }
119
120 bool operator!=(const Optional& other) const {
121 return !this->operator==(other);
122 }
123
124 private:
125 void init(const T& value) {
126 DCHECK(is_null_);
127 new (buffer_.template data_as<T>()) T(value);
128 is_null_ = false;
129 }
130
131 void init_or_assign(const T& value) {
132 if (is_null_)
133 init(value);
134 else
135 *buffer_.template data_as<T>() = value;
136 }
137
138 void free_if_needed() {
139 if (is_null_)
140 return;
141 buffer_.template data_as<T>()->~T();
142 is_null_ = true;
143 }
144
145 bool is_null_;
146 base::AlignedMemory<sizeof(T), ALIGNOF(T)> buffer_;
147 };
148
149 } // namespace base
150
151 #endif // BASE_OPTIONAL_H_
OLDNEW
« 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