1/**
2 * Implementation of an 'Optional' type
3 *
4 * Copyright:   Copyright (C) 1999-2022 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 */
11module dmd.root.optional;
12
13nothrow:
14
15///
16unittest
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`
42extern (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}
91