1 /**
2  * Implementation of an 'Optional' type
3  *
4  * Copyright:   Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
5  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
6  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/root/optional.d, root/_optional.d)
8  * Documentation:  https://dlang.org/phobos/dmd_root_optional.html
9  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/root/optional.d
10  */
11 module dmd.root.optional;
12 
13 nothrow:
14 
15 ///
16 unittest
17 {
18     import core.exception : AssertError;
19 
20     Optional!int opt;
21     assert( opt.isEmpty());
22     assert(!opt.isPresent());
23     assert(!opt.hasValue(1));
24     assert(!opt.hasValue(2));
25 
26     bool caught;
27     try
28         cast(void) opt.get();
29     catch (AssertError)
30         caught = true;
31     assert(caught);
32 
33     opt = Optional!int(1);
34     assert(!opt.isEmpty());
35     assert( opt.isPresent());
36     assert( opt.get() == 1);
37     assert( opt.hasValue(1));
38     assert(!opt.hasValue(2));
39 }
40 
41 /// Optional type that is either `empty` or contains a value of type `T`
42 extern (C++) struct Optional(T)
43 {
44     /// the value (if present)
45     private T value;
46 
47     /// whether `value` is set
48     private bool present;
49 
50   nothrow:
51 
52     /// Creates an `Optional` with the given value
53     this(T value)
54     {
55         this.value = value;
56         this.present = true;
57     }
58 
59     // Ctor wrapper for the C++ interface (required by older host compilers)
60     /// ditto
61     static Optional!T create(T val)
62     {
63         return Optional!T(val);
64     }
65 
66     /// Returns: Whether this `Optional` contains a value
67     bool isPresent() const
68     {
69         return this.present;
70     }
71 
72     /// Returns: Whether this `Optional` does not contain a value
73     bool isEmpty() const
74     {
75         return !this.present;
76     }
77 
78     /// Returns: The value if present
79     inout(T) get() inout
80     {
81         assert(present);
82         return value;
83     }
84 
85     /// Returns: Whether this `Optional` contains the supplied value
86     bool hasValue(const T exp) const
87     {
88         return present && value == exp;
89     }
90 }