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

Side by Side Diff: base/optional.h

Issue 2453733002: Fix base::Optional constexpr ctor on gcc 4.8. (Closed)
Patch Set: Created 4 years, 1 month 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 | no next file » | no next file with comments »
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 constexpr OptionalStorage() {} 37 // Initializing |empty_| here to avoid errors in g++ 4.8.
38 constexpr OptionalStorage() : empty_('\0') {}
38 39
39 constexpr explicit OptionalStorage(const T& value) 40 constexpr explicit OptionalStorage(const T& value)
40 : is_null_(false), value_(value) {} 41 : is_null_(false), value_(value) {}
41 42
42 // TODO(alshabalin): Can't use 'constexpr' with std::move until C++14. 43 // TODO(alshabalin): Can't use 'constexpr' with std::move until C++14.
43 explicit OptionalStorage(T&& value) 44 explicit OptionalStorage(T&& value)
44 : is_null_(false), value_(std::move(value)) {} 45 : is_null_(false), value_(std::move(value)) {}
45 46
46 // TODO(alshabalin): Can't use 'constexpr' with std::forward until C++14. 47 // TODO(alshabalin): Can't use 'constexpr' with std::forward until C++14.
47 template <class... Args> 48 template <class... Args>
48 explicit OptionalStorage(base::in_place_t, Args&&... args) 49 explicit OptionalStorage(base::in_place_t, Args&&... args)
49 : is_null_(false), value_(std::forward<Args>(args)...) {} 50 : is_null_(false), value_(std::forward<Args>(args)...) {}
50 51
51 // When T is not trivially destructible we must call its 52 // When T is not trivially destructible we must call its
52 // destructor before deallocating its memory. 53 // destructor before deallocating its memory.
53 ~OptionalStorage() { 54 ~OptionalStorage() {
54 if (!is_null_) 55 if (!is_null_)
55 value_.~T(); 56 value_.~T();
56 } 57 }
57 58
58 bool is_null_ = true; 59 bool is_null_ = true;
59 union { 60 union {
60 // |empty_| exists so that the union will always be initialized, even when 61 // |empty_| exists so that the union will always be initialized, even when
61 // it doesn't contain a value. Not initializing it has been observed to 62 // it doesn't contain a value. Not initializing it has been observed to
62 // trigger comiler warnings. 63 // trigger comiler warnings.
63 char empty_ = '\0'; 64 char empty_ = '\0';
danakj 2016/10/26 18:56:49 can you drop the \0 here then cuz it's redundant
alshabalin 2016/10/26 20:42:38 Done.
64 T value_; 65 T value_;
65 }; 66 };
66 }; 67 };
67 68
68 template <typename T> 69 template <typename T>
69 struct OptionalStorage<T, true> { 70 struct OptionalStorage<T, true> {
70 constexpr OptionalStorage() {} 71 // Initializing |empty_| here to avoid errors in g++ 4.8.
72 constexpr OptionalStorage() : empty_('\0') {}
71 73
72 constexpr explicit OptionalStorage(const T& value) 74 constexpr explicit OptionalStorage(const T& value)
73 : is_null_(false), value_(value) {} 75 : is_null_(false), value_(value) {}
74 76
75 // TODO(alshabalin): Can't use 'constexpr' with std::move until C++14. 77 // TODO(alshabalin): Can't use 'constexpr' with std::move until C++14.
76 explicit OptionalStorage(T&& value) 78 explicit OptionalStorage(T&& value)
77 : is_null_(false), value_(std::move(value)) {} 79 : is_null_(false), value_(std::move(value)) {}
78 80
79 // TODO(alshabalin): Can't use 'constexpr' with std::forward until C++14. 81 // TODO(alshabalin): Can't use 'constexpr' with std::forward until C++14.
80 template <class... Args> 82 template <class... Args>
81 explicit OptionalStorage(base::in_place_t, Args&&... args) 83 explicit OptionalStorage(base::in_place_t, Args&&... args)
82 : is_null_(false), value_(std::forward<Args>(args)...) {} 84 : is_null_(false), value_(std::forward<Args>(args)...) {}
83 85
84 // When T is trivially destructible (i.e. its destructor does nothing) there 86 // When T is trivially destructible (i.e. its destructor does nothing) there
85 // is no need to call it. Explicitly defaulting the destructor means it's not 87 // is no need to call it. Explicitly defaulting the destructor means it's not
86 // user-provided. Those two together make this destructor trivial. 88 // user-provided. Those two together make this destructor trivial.
87 ~OptionalStorage() = default; 89 ~OptionalStorage() = default;
88 90
89 bool is_null_ = true; 91 bool is_null_ = true;
90 union { 92 union {
91 // |empty_| exists so that the union will always be initialized, even when 93 // |empty_| exists so that the union will always be initialized, even when
92 // it doesn't contain a value. Not initializing it has been observed to 94 // it doesn't contain a value. Not initializing it has been observed to
93 // trigger comiler warnings. 95 // trigger comiler warnings.
94 char empty_ = '\0'; 96 char empty_ = '\0';
danakj 2016/10/26 18:56:49 same
alshabalin 2016/10/26 20:42:38 Done.
95 T value_; 97 T value_;
96 }; 98 };
97 }; 99 };
98 100
99 } // namespace internal 101 } // namespace internal
100 102
101 // base::Optional is a Chromium version of the C++17 optional class: 103 // base::Optional is a Chromium version of the C++17 optional class:
102 // std::optional documentation: 104 // std::optional documentation:
103 // http://en.cppreference.com/w/cpp/utility/optional 105 // http://en.cppreference.com/w/cpp/utility/optional
104 // Chromium documentation: 106 // Chromium documentation:
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 template <class T> 495 template <class T>
494 struct hash<base::Optional<T>> { 496 struct hash<base::Optional<T>> {
495 size_t operator()(const base::Optional<T>& opt) const { 497 size_t operator()(const base::Optional<T>& opt) const {
496 return opt == base::nullopt ? 0 : std::hash<T>()(*opt); 498 return opt == base::nullopt ? 0 : std::hash<T>()(*opt);
497 } 499 }
498 }; 500 };
499 501
500 } // namespace std 502 } // namespace std
501 503
502 #endif // BASE_OPTIONAL_H_ 504 #endif // BASE_OPTIONAL_H_
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698