OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_SCOPED_GENERIC_H_ | 5 #ifndef BASE_SCOPED_GENERIC_H_ |
6 #define BASE_SCOPED_GENERIC_H_ | 6 #define BASE_SCOPED_GENERIC_H_ |
7 | 7 |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 // | 46 // |
47 // // This free function will not be called if f == InvalidValue()! | 47 // // This free function will not be called if f == InvalidValue()! |
48 // static void Free(int f) { | 48 // static void Free(int f) { |
49 // ::FreeFoo(f); | 49 // ::FreeFoo(f); |
50 // } | 50 // } |
51 // }; | 51 // }; |
52 // | 52 // |
53 // typedef ScopedGeneric<int, FooScopedTraits> ScopedFoo; | 53 // typedef ScopedGeneric<int, FooScopedTraits> ScopedFoo; |
54 template<typename T, typename Traits> | 54 template<typename T, typename Traits> |
55 class ScopedGeneric { | 55 class ScopedGeneric { |
56 MOVE_ONLY_TYPE_FOR_CPP_03(ScopedGeneric, RValue) | 56 MOVE_ONLY_TYPE_WITH_MOVE_CONSTRUCTOR_FOR_CPP_03(ScopedGeneric) |
57 | 57 |
58 private: | 58 private: |
59 // This must be first since it's used inline below. | 59 // This must be first since it's used inline below. |
60 // | 60 // |
61 // Use the empty base class optimization to allow us to have a D | 61 // Use the empty base class optimization to allow us to have a D |
62 // member, while avoiding any space overhead for it when D is an | 62 // member, while avoiding any space overhead for it when D is an |
63 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good | 63 // empty class. See e.g. http://www.cantrip.org/emptyopt.html for a good |
64 // discussion of this technique. | 64 // discussion of this technique. |
65 struct Data : public Traits { | 65 struct Data : public Traits { |
66 explicit Data(const T& in) : generic(in) {} | 66 explicit Data(const T& in) : generic(in) {} |
67 Data(const T& in, const Traits& other) : Traits(other), generic(in) {} | 67 Data(const T& in, const Traits& other) : Traits(other), generic(in) {} |
68 T generic; | 68 T generic; |
69 }; | 69 }; |
70 | 70 |
71 public: | 71 public: |
72 typedef T element_type; | 72 typedef T element_type; |
73 typedef Traits traits_type; | 73 typedef Traits traits_type; |
74 | 74 |
75 ScopedGeneric() : data_(traits_type::InvalidValue()) {} | 75 ScopedGeneric() : data_(traits_type::InvalidValue()) {} |
76 | 76 |
77 // Constructor. Takes responsibility for freeing the resource associated with | 77 // Constructor. Takes responsibility for freeing the resource associated with |
78 // the object T. | 78 // the object T. |
79 explicit ScopedGeneric(const element_type& value) : data_(value) {} | 79 explicit ScopedGeneric(const element_type& value) : data_(value) {} |
80 | 80 |
81 // Constructor. Allows initialization of a stateful traits object. | 81 // Constructor. Allows initialization of a stateful traits object. |
82 ScopedGeneric(const element_type& value, const traits_type& traits) | 82 ScopedGeneric(const element_type& value, const traits_type& traits) |
83 : data_(value, traits) { | 83 : data_(value, traits) { |
84 } | 84 } |
85 | 85 |
86 // Move constructor for C++03 move emulation. | 86 // Move constructor. Allows initialization from a ScopedGeneric rvalue. |
87 ScopedGeneric(RValue rvalue) | 87 ScopedGeneric(ScopedGeneric<T, Traits>&& rvalue) |
88 : data_(rvalue.object->release(), rvalue.object->get_traits()) { | 88 : data_(rvalue.release(), rvalue.get_traits()) { |
89 } | 89 } |
90 | 90 |
91 ~ScopedGeneric() { | 91 ~ScopedGeneric() { |
92 FreeIfNecessary(); | 92 FreeIfNecessary(); |
93 } | 93 } |
94 | 94 |
| 95 // operator=. Allows assignment from a ScopedGeneric rvalue. |
| 96 ScopedGeneric& operator=(ScopedGeneric<T, Traits>&& rvalue) { |
| 97 reset(rvalue.release()); |
| 98 return *this; |
| 99 } |
| 100 |
95 // Frees the currently owned object, if any. Then takes ownership of a new | 101 // Frees the currently owned object, if any. Then takes ownership of a new |
96 // object, if given. Self-resets are not allowd as on scoped_ptr. See | 102 // object, if given. Self-resets are not allowd as on scoped_ptr. See |
97 // http://crbug.com/162971 | 103 // http://crbug.com/162971 |
98 void reset(const element_type& value = traits_type::InvalidValue()) { | 104 void reset(const element_type& value = traits_type::InvalidValue()) { |
99 if (data_.generic != traits_type::InvalidValue() && data_.generic == value) | 105 if (data_.generic != traits_type::InvalidValue() && data_.generic == value) |
100 abort(); | 106 abort(); |
101 FreeIfNecessary(); | 107 FreeIfNecessary(); |
102 data_.generic = value; | 108 data_.generic = value; |
103 } | 109 } |
104 | 110 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 173 } |
168 | 174 |
169 template<class T, class Traits> | 175 template<class T, class Traits> |
170 bool operator!=(const T& value, const ScopedGeneric<T, Traits>& scoped) { | 176 bool operator!=(const T& value, const ScopedGeneric<T, Traits>& scoped) { |
171 return value != scoped.get(); | 177 return value != scoped.get(); |
172 } | 178 } |
173 | 179 |
174 } // namespace base | 180 } // namespace base |
175 | 181 |
176 #endif // BASE_SCOPED_GENERIC_H_ | 182 #endif // BASE_SCOPED_GENERIC_H_ |
OLD | NEW |