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

Side by Side Diff: base/optional.h

Issue 2434253003: Make base::Optional constructor constexpr. (Closed)
Patch Set: Make value constructors constexpr. Created 4 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 | « no previous file | base/optional_unittest.cc » ('j') | base/optional_unittest.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_OPTIONAL_H_ 5 #ifndef BASE_OPTIONAL_H_
6 #define BASE_OPTIONAL_H_ 6 #define BASE_OPTIONAL_H_
7 7
8 #include <type_traits> 8 #include <type_traits>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 16 matching lines...) Expand all
27 constexpr in_place_t in_place = {}; 27 constexpr in_place_t in_place = {};
28 28
29 // Specification: 29 // Specification:
30 // http://en.cppreference.com/w/cpp/utility/optional/nullopt 30 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
31 constexpr nullopt_t nullopt(0); 31 constexpr nullopt_t nullopt(0);
32 32
33 namespace internal { 33 namespace internal {
34 34
35 template <typename T, bool = base::is_trivially_destructible<T>::value> 35 template <typename T, bool = base::is_trivially_destructible<T>::value>
36 struct OptionalStorage { 36 struct OptionalStorage {
37 OptionalStorage() {} 37 constexpr OptionalStorage() {}
38 constexpr explicit OptionalStorage(const T& value)
39 : is_null_(false), value_(value) {}
40 constexpr explicit OptionalStorage(T&& value)
41 : is_null_(false), value_(std::move(value)) {}
42 template <class... Args>
43 constexpr explicit OptionalStorage(base::in_place_t, Args&&... args)
44 : is_null_(false), value_(std::forward<Args>(args)...) {}
38 // When T is not trivially destructible we must call its 45 // When T is not trivially destructible we must call its
danakj 2016/10/21 23:12:08 nit: whitespace above this to separate it since we
alshabalin 2016/10/22 07:47:52 Done.
39 // destructor before deallocating its memory. 46 // destructor before deallocating its memory.
40 ~OptionalStorage() { 47 ~OptionalStorage() {
41 if (!is_null_) 48 if (!is_null_)
42 value_.~T(); 49 value_.~T();
43 } 50 }
44 51
45 bool is_null_ = true; 52 bool is_null_ = true;
46 union { 53 union {
47 // |empty_| exists so that the union will always be initialized, even when 54 // |empty_| exists so that the union will always be initialized, even when
48 // it doesn't contain a value. Not initializing it has been observed to 55 // it doesn't contain a value. Not initializing it has been observed to
49 // trigger comiler warnings. 56 // trigger comiler warnings.
50 char empty_ = '\0'; 57 char empty_ = '\0';
51 T value_; 58 T value_;
52 }; 59 };
53 }; 60 };
54 61
55 template <typename T> 62 template <typename T>
56 struct OptionalStorage<T, true> { 63 struct OptionalStorage<T, true> {
57 OptionalStorage() {} 64 constexpr OptionalStorage() {}
65 constexpr explicit OptionalStorage(const T& value)
66 : is_null_(false), value_(value) {}
67 constexpr explicit OptionalStorage(T&& value)
68 : is_null_(false), value_(std::move(value)) {}
69 template <class... Args>
70 constexpr explicit OptionalStorage(base::in_place_t, Args&&... args)
71 : is_null_(false), value_(std::forward<Args>(args)...) {}
58 // When T is trivially destructible (i.e. its destructor does nothing) there 72 // When T is trivially destructible (i.e. its destructor does nothing) there
danakj 2016/10/21 23:12:08 same
alshabalin 2016/10/22 07:47:51 Done.
59 // is no need to call it. Explicitly defaulting the destructor means it's not 73 // is no need to call it. Explicitly defaulting the destructor means it's not
60 // user-provided. Those two together make this destructor trivial. 74 // user-provided. Those two together make this destructor trivial.
61 ~OptionalStorage() = default; 75 ~OptionalStorage() = default;
62 76
63 bool is_null_ = true; 77 bool is_null_ = true;
64 union { 78 union {
65 // |empty_| exists so that the union will always be initialized, even when 79 // |empty_| exists so that the union will always be initialized, even when
66 // it doesn't contain a value. Not initializing it has been observed to 80 // it doesn't contain a value. Not initializing it has been observed to
67 // trigger comiler warnings. 81 // trigger comiler warnings.
68 char empty_ = '\0'; 82 char empty_ = '\0';
(...skipping 15 matching lines...) Expand all
84 // - Constructors do not use 'constexpr' as it is a C++14 extension. 98 // - Constructors do not use 'constexpr' as it is a C++14 extension.
85 // - 'constexpr' might be missing in some places for reasons specified locally. 99 // - 'constexpr' might be missing in some places for reasons specified locally.
86 // - No exceptions are thrown, because they are banned from Chromium. 100 // - No exceptions are thrown, because they are banned from Chromium.
87 // - All the non-members are in the 'base' namespace instead of 'std'. 101 // - All the non-members are in the 'base' namespace instead of 'std'.
88 template <typename T> 102 template <typename T>
89 class Optional { 103 class Optional {
90 public: 104 public:
91 using value_type = T; 105 using value_type = T;
92 106
93 constexpr Optional() = default; 107 constexpr Optional() = default;
94 Optional(base::nullopt_t) : Optional() {} 108 constexpr Optional(base::nullopt_t) : Optional() {}
95 109
96 Optional(const Optional& other) { 110 Optional(const Optional& other) {
97 if (!other.storage_.is_null_) 111 if (!other.storage_.is_null_)
98 Init(other.value()); 112 Init(other.value());
99 } 113 }
100 114
101 Optional(Optional&& other) { 115 Optional(Optional&& other) {
102 if (!other.storage_.is_null_) 116 if (!other.storage_.is_null_)
103 Init(std::move(other.value())); 117 Init(std::move(other.value()));
104 } 118 }
105 119
106 Optional(const T& value) { Init(value); } 120 constexpr Optional(const T& value) : storage_(value) {}
107 121
108 Optional(T&& value) { Init(std::move(value)); } 122 constexpr Optional(T&& value) : storage_(std::move(value)) {}
109 123
110 template <class... Args> 124 template <class... Args>
111 explicit Optional(base::in_place_t, Args&&... args) { 125 constexpr explicit Optional(base::in_place_t, Args&&... args)
112 emplace(std::forward<Args>(args)...); 126 : storage_(base::in_place, std::forward<Args>(args)...) {}
113 }
114 127
115 ~Optional() = default; 128 ~Optional() = default;
116 129
117 Optional& operator=(base::nullopt_t) { 130 Optional& operator=(base::nullopt_t) {
118 FreeIfNeeded(); 131 FreeIfNeeded();
119 return *this; 132 return *this;
120 } 133 }
121 134
122 Optional& operator=(const Optional& other) { 135 Optional& operator=(const Optional& other) {
123 if (other.storage_.is_null_) { 136 if (other.storage_.is_null_) {
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 template <class T> 478 template <class T>
466 struct hash<base::Optional<T>> { 479 struct hash<base::Optional<T>> {
467 size_t operator()(const base::Optional<T>& opt) const { 480 size_t operator()(const base::Optional<T>& opt) const {
468 return opt == base::nullopt ? 0 : std::hash<T>()(*opt); 481 return opt == base::nullopt ? 0 : std::hash<T>()(*opt);
469 } 482 }
470 }; 483 };
471 484
472 } // namespace std 485 } // namespace std
473 486
474 #endif // BASE_OPTIONAL_H_ 487 #endif // BASE_OPTIONAL_H_
OLDNEW
« no previous file with comments | « no previous file | base/optional_unittest.cc » ('j') | base/optional_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698