Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / src / lib / core / Optional.h
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *    Unless required by applicable law or agreed to in writing, software
12  *    distributed under the License is distributed on an "AS IS" BASIS,
13  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *    See the License for the specific language governing permissions and
15  *    limitations under the License.
16  */
17
18 /**
19  *    @file
20  *      This file defines the chip::Optional class to handle values which may
21  *      or may not be present.
22  *
23  */
24 #pragma once
25
26 #include <assert.h>
27
28 namespace chip {
29
30 /**
31  * Pairs an object with a boolean value to determine if the object value
32  * is actually valid or not.
33  */
34 template <class T>
35 class Optional
36 {
37 public:
38     constexpr Optional() : mHasValue(false) {}
39     explicit Optional(const T & value) : mValue(value), mHasValue(true) {}
40
41     constexpr Optional(const Optional & other) = default;
42     constexpr Optional(Optional && other)      = default;
43
44     /**
45      * Assignment operator implementation.
46      *
47      * NOTE: Manually implemented instead of =default  since other::mValue may not be initialized
48      * if it has no value.
49      */
50     constexpr Optional & operator=(const Optional & other)
51     {
52         if (other.HasValue())
53         {
54             SetValue(other.Value());
55         }
56         else
57         {
58             ClearValue();
59         }
60         return *this;
61     }
62
63     /** Make the optional contain a specific value */
64     constexpr void SetValue(const T & value)
65     {
66         mValue    = value;
67         mHasValue = true;
68     }
69
70     /** Invalidate the value inside the optional. Optional now has no value */
71     constexpr void ClearValue() { mHasValue = false; }
72
73     /** Gets the current value of the optional. Valid IFF `HasValue`. */
74     const T & Value() const
75     {
76         assert(HasValue());
77         return mValue;
78     }
79
80     /** Gets the current value of the optional if the optional has a value;
81         otherwise returns the provided default value. */
82     const T & ValueOr(const T & defaultValue) const
83     {
84         if (HasValue())
85         {
86             return mValue;
87         }
88         return defaultValue;
89     }
90
91     /** Checks if the optional contains a value or not */
92     constexpr bool HasValue() const { return mHasValue; }
93
94     /** Comparison operator, handling missing values. */
95     bool operator==(const Optional & other) const
96     {
97         return (mHasValue == other.mHasValue) && (!other.mHasValue || (mValue == other.mValue));
98     }
99
100     /** Comparison operator, handling missing values. */
101     bool operator!=(const Optional & other) const { return !(*this == other); }
102
103     /** Convenience method to create an optional without a valid value. */
104     static Optional<T> Missing() { return Optional<T>(); }
105
106     /** Convenience method to create an optional containing the specified value. */
107     static Optional<T> Value(const T & value) { return Optional(value); }
108
109 private:
110     T mValue;       ///< Value IFF optional contains a value
111     bool mHasValue; ///< True IFF optional contains a value
112 };
113
114 } // namespace chip