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

Side by Side Diff: base/optional.h

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