blob: fee3a1a4bd90679eddc39935692a8cd284b4c002 [file] [log] [blame] [view]
mlamouri53f6b252016-04-19 17:27:011# base::Optional
2
3`base::Optional<T>` is a container that might contain an instance of `T`.
4
5[TOC]
6
7## History
8
9[base::Optional<T>](https://code.google.com/p/chromium/codesearch#chromium/src/base/optional.h)
10is an implementation of [std::optional<T>](http://en.cppreference.com/w/cpp/utility/optional),
11initially a C++ experimental feature and now part of the C++17 standard. The
12Chromium's implementation is as close as possible to the specification. The
13differences are listed at the beginning of the header. The most important
14difference is that all the objects and types are part of the `base::` namespace
15instead of `std::`. Also, following Chromium coding style, the class is named
16`Optional` instead of `optional`.
17
18## API description
19
20For a deep API description, please have a look at [std::optional<T>](http://en.cppreference.com/w/cpp/utility/optional)
21or the [Chromium implementation](https://code.google.com/p/chromium/codesearch#chromium/src/base/optional.h).
22
23When initialized without a value, `base::Optional<T>` will be empty. When empty,
24the `operator bool` will return `false` and `value()` should not be called. An
Klaus Weidner743db5a2017-09-13 17:43:0625empty `base::Optional<T>` is equal to `base::nullopt`.
mlamouri53f6b252016-04-19 17:27:0126
27```C++
28base::Optional<int> opt;
29opt == true; // false
30opt.value(); // illegal, will DCHECK
Klaus Weidner743db5a2017-09-13 17:43:0631opt == base::nullopt; // true
32```
33
34To pass an empty optional argument to another function, use `base::nullopt`
35where you would otherwise have used a `nullptr`:
36
37``` C++
38OtherFunction(42, base::nullopt); // Supply an empty optional argument
mlamouri53f6b252016-04-19 17:27:0139```
40
41To avoid calling `value()` when an `base::Optional<T>` is empty, instead of
42doing checks, it is possible to use `value_or()` and pass a default value:
43
44```C++
45base::Optional<int> opt;
46opt.value_or(42); // will return 42
47```
48
49It is possible to initialize a `base::Optional<T>` from its constructor and
50`operator=` using `T` or another `base::Optional<T>`:
51
52```C++
53base::Optional<int> opt_1 = 1; // .value() == 1
54base::Optional<int> opt_2 = base::Optional<int>(2); // .value() == 2
55```
56
57All basic operators should be available on `base::Optional<T>`: it is possible
58to compare a `base::Optional<T>` with another or with a `T` or
Klaus Weidner743db5a2017-09-13 17:43:0659`base::nullopt`.
mlamouri53f6b252016-04-19 17:27:0160
61```C++
62base::Optional<int> opt_1;
63base::Optional<int> opt_2 = 2;
64
65opt_1 == opt_2; // false
66opt_1 = 1;
67
68opt_1 <= opt_2; // true
69opt_1 == 1; // true
Klaus Weidner743db5a2017-09-13 17:43:0670opt_1 == base::nullopt; // false
mlamouri53f6b252016-04-19 17:27:0171```
72
michaelpg4a9c82e2017-03-15 02:44:2673`base::Optional<T>` has a helper function `base::make_optional<T&&>`:
mlamouri53f6b252016-04-19 17:27:0174
75```C++
michaelpg4a9c82e2017-03-15 02:44:2676base::Optional<int> opt = base::make_optional<int>(GetMagicNumber());
mlamouri53f6b252016-04-19 17:27:0177```
78
79Finally, `base::Optional<T>` is integrated with `std::hash`, using
80`std::hash<T>` if it is not empty, a default value otherwise. `.emplace()` and
81`.swap()` can be used as members functions and `std::swap()` will work with two
82`base::Optional<T>` objects.
83
84## How is it implemented?
85
kwiberg882859a2016-08-16 09:42:2186`base::Optional<T>` is implemented with a union with a `T` member. The object
mlamouri53f6b252016-04-19 17:27:0187doesn't behave like a pointer and doesn't do dynamic memory allocation. In
88other words, it is guaranteed to have an object allocated when it is not empty.
89
90## When to use?
91
92A very common use case is for classes and structures that have an object not
93always available, because it is early initialized or because the underlying data
94structure doesn't require it.
95
96It is common to implement such patterns with dynamically allocated pointers,
97`nullptr` representing the absence of value. Other approaches involve
98`std::pair<T, bool>` where bool represents whether the object is actually
99present.
100
101It can also be used for simple types, for example when a structure wants to
102represent whether the user or the underlying data structure has some value
103unspecified, a `base::Optional<int>` would be easier to understand than a
104special value representing the lack of it. For example, using -1 as the
105undefined value when the expected value can't be negative.
106
107## When not to use?
108
109It is recommended to not use `base::Optional<T>` as a function parameter as it
110will force the callers to use `base::Optional<T>`. Instead, it is recommended to
qyearsleyc0dc6f42016-12-02 22:13:39111keep using `T*` for arguments that can be omitted, with `nullptr` representing
Philip Rogers353fc9f2018-03-16 16:33:05112no value. A helper, `base::OptionalOrNullptr`, is available in
113[stl_util.h](https://code.google.com/p/chromium/codesearch#chromium/src/base/stl_util.h)
114and can make it easier to convert `base::Optional<T>` to `T*`.
mlamouri53f6b252016-04-19 17:27:01115
116Furthermore, depending on `T`, MSVC might fail to compile code using
117`base::Optional<T>` as a parameter because of memory alignment issues.