1 // Copyright 2022 The Chromium Authors 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_TYPES_OPTIONAL_UTIL_H_ 6 #define BASE_TYPES_OPTIONAL_UTIL_H_ 7 8 #include "third_party/abseil-cpp/absl/types/optional.h" 9 10 namespace base { 11 12 // Helper for converting an `absl::optional<T>` to a pointer suitable for 13 // passing as a function argument: 14 // 15 // void MaybeProcessData(const std::string* optional_data); 16 // 17 // class Example { 18 // public: 19 // void DoSomething() { 20 // MaybeProcessData(base::OptionalToPtr(data_)); 21 // } 22 // 23 // private: 24 // absl::optional<std::string> data_; 25 // }; 26 // 27 // Rationale: per the C++ style guide, if `T` would normally be passed by 28 // reference, the optional version should be passed as `T*`, and *not* as 29 // `const absl::optional<T>&`. Passing as `const absl::optional<T>&` leads to 30 // implicit constructions and copies, e.g.: 31 // 32 // // BAD: a caller passing a `std::string` implicitly copies the entire string 33 // // to construct a temporary `absl::optional<std::string>` to use for the 34 // // function argument. 35 // void BadMaybeProcessData(const absl::optional<std::string>& optional_data); 36 // 37 // For more background, see https://abseil.io/tips/163. 38 template <class T> OptionalToPtr(const absl::optional<T> & optional)39const T* OptionalToPtr(const absl::optional<T>& optional) { 40 return optional.has_value() ? &optional.value() : nullptr; 41 } 42 43 template <class T> OptionalToPtr(absl::optional<T> & optional)44T* OptionalToPtr(absl::optional<T>& optional) { 45 return optional.has_value() ? &optional.value() : nullptr; 46 } 47 48 // Helper for creating an `absl::optional<T>` from a `T*` which may be null. 49 template <class T> OptionalFromPtr(const T * value)50absl::optional<T> OptionalFromPtr(const T* value) { 51 return value ? absl::optional<T>(*value) : absl::nullopt; 52 } 53 54 } // namespace base 55 56 #endif // BASE_TYPES_OPTIONAL_UTIL_H_ 57