blob: a2220316ab36ee2976312ebfbc9bbf4339de0e96 [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
25empty `base::Optional<T>` is equal to `base::nullopt_t`.
26
27```C++
28base::Optional<int> opt;
29opt == true; // false
30opt.value(); // illegal, will DCHECK
31opt == base::nullopt_t; // true
32```
33
34To avoid calling `value()` when an `base::Optional<T>` is empty, instead of
35doing checks, it is possible to use `value_or()` and pass a default value:
36
37```C++
38base::Optional<int> opt;
39opt.value_or(42); // will return 42
40```
41
42It is possible to initialize a `base::Optional<T>` from its constructor and
43`operator=` using `T` or another `base::Optional<T>`:
44
45```C++
46base::Optional<int> opt_1 = 1; // .value() == 1
47base::Optional<int> opt_2 = base::Optional<int>(2); // .value() == 2
48```
49
50All basic operators should be available on `base::Optional<T>`: it is possible
51to compare a `base::Optional<T>` with another or with a `T` or
52`base::nullopt_t`.
53
54```C++
55base::Optional<int> opt_1;
56base::Optional<int> opt_2 = 2;
57
58opt_1 == opt_2; // false
59opt_1 = 1;
60
61opt_1 <= opt_2; // true
62opt_1 == 1; // true
63opt_1 == base::nullopt_t; // false
64```
65
66`base::Optional<T>` has a helper function `make_optional<T&&>`:
67
68```C++
69base::Optional<int> opt = make_optional<int>(GetMagicNumber());
70```
71
72Finally, `base::Optional<T>` is integrated with `std::hash`, using
73`std::hash<T>` if it is not empty, a default value otherwise. `.emplace()` and
74`.swap()` can be used as members functions and `std::swap()` will work with two
75`base::Optional<T>` objects.
76
77## How is it implemented?
78
79`base::Optional<T>` is implemented using `base::AlignedMemory`. The object
80doesn't behave like a pointer and doesn't do dynamic memory allocation. In
81other words, it is guaranteed to have an object allocated when it is not empty.
82
83## When to use?
84
85A very common use case is for classes and structures that have an object not
86always available, because it is early initialized or because the underlying data
87structure doesn't require it.
88
89It is common to implement such patterns with dynamically allocated pointers,
90`nullptr` representing the absence of value. Other approaches involve
91`std::pair<T, bool>` where bool represents whether the object is actually
92present.
93
94It can also be used for simple types, for example when a structure wants to
95represent whether the user or the underlying data structure has some value
96unspecified, a `base::Optional<int>` would be easier to understand than a
97special value representing the lack of it. For example, using -1 as the
98undefined value when the expected value can't be negative.
99
100## When not to use?
101
102It is recommended to not use `base::Optional<T>` as a function parameter as it
103will force the callers to use `base::Optional<T>`. Instead, it is recommended to
104keep using `T*` for arguments that can be ommited, with `nullptr` representing
105no value.
106
107Furthermore, depending on `T`, MSVC might fail to compile code using
108`base::Optional<T>` as a parameter because of memory alignment issues.