// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MOJO_PUBLIC_CPP_BINDINGS_OPTIONAL_AS_POINTER_H_ #define MOJO_PUBLIC_CPP_BINDINGS_OPTIONAL_AS_POINTER_H_ #include <cstddef> #include "base/memory/raw_ptr.h" namespace mojo { // Simple wrapper around a pointer to allow zero-copy serialization of a // nullable type. // // Traits for nullable fields typically return `const std::optional<T>&` or // `std::optional<T>&`. However, if the field is not already an // `std::optional`, this can be inefficient: // // static std::optional<std::string> nullable_field_getter( // const MyType& input) { // // Bad: copies input.data() to populate `std::optional`. // return std::make_optional( // input.has_valid_data() ? input.data() : std::nullopt); // } // // Using this wrapper allows this to be serialized without additional copies: // // static mojo::OptionalAsPointer<std::string> nullable_field_getter( // const MyType& input) { // return mojo::OptionalAsPointer( // input.has_valid_data() ? &input.data() : nullptr); // } // // N.B. The original prototype for reducing copies in serialization attempted to // use C++ pointers directly; unfortunately, some Windows SDK opaque handle // types are actually defined as a pointer to a struct, which confused the Mojo // serialization traits. While it is possible to block the problematic types, // having an actual type makes the intent more explicit. template <typename T> class OptionalAsPointer { … }; template <typename T> OptionalAsPointer(T*) -> OptionalAsPointer<T>; } // namespace mojo #endif // MOJO_PUBLIC_CPP_BINDINGS_OPTIONAL_AS_POINTER_H_