xref: /aosp_15_r20/build/blueprint/optional/optional.go (revision 1fa6dee971e1612fa5cc0aa5ca2d35a22e2c34a3)
1*1fa6dee9SAndroid Build Coastguard Worker// Copyright 2023 Google Inc. All rights reserved.
2*1fa6dee9SAndroid Build Coastguard Worker//
3*1fa6dee9SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*1fa6dee9SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*1fa6dee9SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*1fa6dee9SAndroid Build Coastguard Worker//
7*1fa6dee9SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*1fa6dee9SAndroid Build Coastguard Worker//
9*1fa6dee9SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*1fa6dee9SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*1fa6dee9SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*1fa6dee9SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*1fa6dee9SAndroid Build Coastguard Worker// limitations under the License.
14*1fa6dee9SAndroid Build Coastguard Worker
15*1fa6dee9SAndroid Build Coastguard Workerpackage optional
16*1fa6dee9SAndroid Build Coastguard Worker
17*1fa6dee9SAndroid Build Coastguard Worker// ShallowOptional is an optional type that can be constructed from a pointer.
18*1fa6dee9SAndroid Build Coastguard Worker// It will not copy the pointer, and its size is the same size as a single pointer.
19*1fa6dee9SAndroid Build Coastguard Worker// It can be used to prevent a downstream consumer from modifying the value through
20*1fa6dee9SAndroid Build Coastguard Worker// the pointer, but is not suitable for an Optional type with stronger value semantics
21*1fa6dee9SAndroid Build Coastguard Worker// like you would expect from C++ or Rust Optionals.
22*1fa6dee9SAndroid Build Coastguard Workertype ShallowOptional[T any] struct {
23*1fa6dee9SAndroid Build Coastguard Worker	inner *T
24*1fa6dee9SAndroid Build Coastguard Worker}
25*1fa6dee9SAndroid Build Coastguard Worker
26*1fa6dee9SAndroid Build Coastguard Worker// NewShallowOptional creates a new ShallowOptional from a pointer.
27*1fa6dee9SAndroid Build Coastguard Worker// The pointer will not be copied, the object could be changed by the calling
28*1fa6dee9SAndroid Build Coastguard Worker// code after the optional was created.
29*1fa6dee9SAndroid Build Coastguard Workerfunc NewShallowOptional[T any](inner *T) ShallowOptional[T] {
30*1fa6dee9SAndroid Build Coastguard Worker	return ShallowOptional[T]{inner: inner}
31*1fa6dee9SAndroid Build Coastguard Worker}
32*1fa6dee9SAndroid Build Coastguard Worker
33*1fa6dee9SAndroid Build Coastguard Worker// IsPresent returns true if the optional contains a value
34*1fa6dee9SAndroid Build Coastguard Workerfunc (o *ShallowOptional[T]) IsPresent() bool {
35*1fa6dee9SAndroid Build Coastguard Worker	return o.inner != nil
36*1fa6dee9SAndroid Build Coastguard Worker}
37*1fa6dee9SAndroid Build Coastguard Worker
38*1fa6dee9SAndroid Build Coastguard Worker// IsEmpty returns true if the optional does not have a value
39*1fa6dee9SAndroid Build Coastguard Workerfunc (o *ShallowOptional[T]) IsEmpty() bool {
40*1fa6dee9SAndroid Build Coastguard Worker	return o.inner == nil
41*1fa6dee9SAndroid Build Coastguard Worker}
42*1fa6dee9SAndroid Build Coastguard Worker
43*1fa6dee9SAndroid Build Coastguard Worker// Get() returns the value inside the optional. It panics if IsEmpty() returns true
44*1fa6dee9SAndroid Build Coastguard Workerfunc (o *ShallowOptional[T]) Get() T {
45*1fa6dee9SAndroid Build Coastguard Worker	if o.inner == nil {
46*1fa6dee9SAndroid Build Coastguard Worker		panic("tried to get an empty optional")
47*1fa6dee9SAndroid Build Coastguard Worker	}
48*1fa6dee9SAndroid Build Coastguard Worker	return *o.inner
49*1fa6dee9SAndroid Build Coastguard Worker}
50*1fa6dee9SAndroid Build Coastguard Worker
51*1fa6dee9SAndroid Build Coastguard Worker// GetOrDefault() returns the value inside the optional if IsPresent() returns true,
52*1fa6dee9SAndroid Build Coastguard Worker// or the provided value otherwise.
53*1fa6dee9SAndroid Build Coastguard Workerfunc (o *ShallowOptional[T]) GetOrDefault(other T) T {
54*1fa6dee9SAndroid Build Coastguard Worker	if o.inner == nil {
55*1fa6dee9SAndroid Build Coastguard Worker		return other
56*1fa6dee9SAndroid Build Coastguard Worker	}
57*1fa6dee9SAndroid Build Coastguard Worker	return *o.inner
58*1fa6dee9SAndroid Build Coastguard Worker}
59