xref: /minix3/external/bsd/kyua-cli/dist/utils/optional.ipp (revision 11be35a165022172ed3cea20f2b5df0307540b0e)
1*11be35a1SLionel Sambuc// Copyright 2010 Google Inc.
2*11be35a1SLionel Sambuc// All rights reserved.
3*11be35a1SLionel Sambuc//
4*11be35a1SLionel Sambuc// Redistribution and use in source and binary forms, with or without
5*11be35a1SLionel Sambuc// modification, are permitted provided that the following conditions are
6*11be35a1SLionel Sambuc// met:
7*11be35a1SLionel Sambuc//
8*11be35a1SLionel Sambuc// * Redistributions of source code must retain the above copyright
9*11be35a1SLionel Sambuc//   notice, this list of conditions and the following disclaimer.
10*11be35a1SLionel Sambuc// * Redistributions in binary form must reproduce the above copyright
11*11be35a1SLionel Sambuc//   notice, this list of conditions and the following disclaimer in the
12*11be35a1SLionel Sambuc//   documentation and/or other materials provided with the distribution.
13*11be35a1SLionel Sambuc// * Neither the name of Google Inc. nor the names of its contributors
14*11be35a1SLionel Sambuc//   may be used to endorse or promote products derived from this software
15*11be35a1SLionel Sambuc//   without specific prior written permission.
16*11be35a1SLionel Sambuc//
17*11be35a1SLionel Sambuc// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*11be35a1SLionel Sambuc// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*11be35a1SLionel Sambuc// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*11be35a1SLionel Sambuc// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*11be35a1SLionel Sambuc// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*11be35a1SLionel Sambuc// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*11be35a1SLionel Sambuc// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*11be35a1SLionel Sambuc// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*11be35a1SLionel Sambuc// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*11be35a1SLionel Sambuc// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*11be35a1SLionel Sambuc// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*11be35a1SLionel Sambuc
29*11be35a1SLionel Sambuc#if !defined(UTILS_OPTIONAL_IPP)
30*11be35a1SLionel Sambuc#define UTILS_OPTIONAL_IPP
31*11be35a1SLionel Sambuc
32*11be35a1SLionel Sambuc#include <cstddef>
33*11be35a1SLionel Sambuc
34*11be35a1SLionel Sambuc#include "utils/defs.hpp"
35*11be35a1SLionel Sambuc#include "utils/optional.hpp"
36*11be35a1SLionel Sambuc#include "utils/sanity.hpp"
37*11be35a1SLionel Sambuc
38*11be35a1SLionel Sambuc
39*11be35a1SLionel Sambuc/// Initializes an optional object to the none value.
40*11be35a1SLionel Sambuctemplate< class T >
41*11be35a1SLionel Sambucutils::optional< T >::optional(void) :
42*11be35a1SLionel Sambuc    _data(NULL)
43*11be35a1SLionel Sambuc{
44*11be35a1SLionel Sambuc}
45*11be35a1SLionel Sambuc
46*11be35a1SLionel Sambuc
47*11be35a1SLionel Sambuc/// Explicitly initializes an optional object to the none value.
48*11be35a1SLionel Sambuc///
49*11be35a1SLionel Sambuc/// \param unused_none A copy of the utils::none instance.
50*11be35a1SLionel Sambuctemplate< class T >
51*11be35a1SLionel Sambucutils::optional< T >::optional(
52*11be35a1SLionel Sambuc    utils::detail::none_t UTILS_UNUSED_PARAM(none)) :
53*11be35a1SLionel Sambuc    _data(NULL)
54*11be35a1SLionel Sambuc{
55*11be35a1SLionel Sambuc}
56*11be35a1SLionel Sambuc
57*11be35a1SLionel Sambuc
58*11be35a1SLionel Sambuc/// Initializes an optional object to a non-none value.
59*11be35a1SLionel Sambuc///
60*11be35a1SLionel Sambuc/// \param data The initial value for the object.
61*11be35a1SLionel Sambuctemplate< class T >
62*11be35a1SLionel Sambucutils::optional< T >::optional(const T& data) :
63*11be35a1SLionel Sambuc    _data(new T(data))
64*11be35a1SLionel Sambuc{
65*11be35a1SLionel Sambuc}
66*11be35a1SLionel Sambuc
67*11be35a1SLionel Sambuc
68*11be35a1SLionel Sambuc/// Copy constructor.
69*11be35a1SLionel Sambuc///
70*11be35a1SLionel Sambuc/// \param other The optional object to copy from.
71*11be35a1SLionel Sambuctemplate< class T >
72*11be35a1SLionel Sambucutils::optional< T >::optional(const optional< T >& other) :
73*11be35a1SLionel Sambuc    _data(other._data == NULL ? NULL : new T(*(other._data)))
74*11be35a1SLionel Sambuc{
75*11be35a1SLionel Sambuc}
76*11be35a1SLionel Sambuc
77*11be35a1SLionel Sambuc
78*11be35a1SLionel Sambuc/// Destructor.
79*11be35a1SLionel Sambuctemplate< class T >
80*11be35a1SLionel Sambucutils::optional< T >::~optional(void)
81*11be35a1SLionel Sambuc{
82*11be35a1SLionel Sambuc    if (_data != NULL)
83*11be35a1SLionel Sambuc        delete _data;
84*11be35a1SLionel Sambuc    _data = NULL;  // Prevent accidental reuse.
85*11be35a1SLionel Sambuc}
86*11be35a1SLionel Sambuc
87*11be35a1SLionel Sambuc
88*11be35a1SLionel Sambuc/// Explicitly assigns an optional object to the none value.
89*11be35a1SLionel Sambuc///
90*11be35a1SLionel Sambuc/// \param unused_none A copy of the utils::none instance.
91*11be35a1SLionel Sambuc///
92*11be35a1SLionel Sambuc/// \return A reference to this.
93*11be35a1SLionel Sambuctemplate< class T >
94*11be35a1SLionel Sambucutils::optional< T >&
95*11be35a1SLionel Sambucutils::optional< T >::operator=(utils::detail::none_t UTILS_UNUSED_PARAM(none))
96*11be35a1SLionel Sambuc{
97*11be35a1SLionel Sambuc    if (_data != NULL)
98*11be35a1SLionel Sambuc        delete _data;
99*11be35a1SLionel Sambuc    _data = NULL;
100*11be35a1SLionel Sambuc    return *this;
101*11be35a1SLionel Sambuc}
102*11be35a1SLionel Sambuc
103*11be35a1SLionel Sambuc
104*11be35a1SLionel Sambuc/// Assigns a new value to the optional object.
105*11be35a1SLionel Sambuc///
106*11be35a1SLionel Sambuc/// \param data The initial value for the object.
107*11be35a1SLionel Sambuc///
108*11be35a1SLionel Sambuc/// \return A reference to this.
109*11be35a1SLionel Sambuctemplate< class T >
110*11be35a1SLionel Sambucutils::optional< T >&
111*11be35a1SLionel Sambucutils::optional< T >::operator=(const T& data)
112*11be35a1SLionel Sambuc{
113*11be35a1SLionel Sambuc    T* new_data = new T(data);
114*11be35a1SLionel Sambuc    if (_data != NULL)
115*11be35a1SLionel Sambuc        delete _data;
116*11be35a1SLionel Sambuc    _data = new_data;
117*11be35a1SLionel Sambuc    return *this;
118*11be35a1SLionel Sambuc}
119*11be35a1SLionel Sambuc
120*11be35a1SLionel Sambuc
121*11be35a1SLionel Sambuc/// Copies an optional value.
122*11be35a1SLionel Sambuc///
123*11be35a1SLionel Sambuc/// \param other The optional object to copy from.
124*11be35a1SLionel Sambuc///
125*11be35a1SLionel Sambuc/// \return A reference to this.
126*11be35a1SLionel Sambuctemplate< class T >
127*11be35a1SLionel Sambucutils::optional< T >&
128*11be35a1SLionel Sambucutils::optional< T >::operator=(const optional< T >& other)
129*11be35a1SLionel Sambuc{
130*11be35a1SLionel Sambuc    T* new_data = other._data == NULL ? NULL : new T(*(other._data));
131*11be35a1SLionel Sambuc    if (_data != NULL)
132*11be35a1SLionel Sambuc        delete _data;
133*11be35a1SLionel Sambuc    _data = new_data;
134*11be35a1SLionel Sambuc    return *this;
135*11be35a1SLionel Sambuc}
136*11be35a1SLionel Sambuc
137*11be35a1SLionel Sambuc
138*11be35a1SLionel Sambuc/// Equality comparator.
139*11be35a1SLionel Sambuc///
140*11be35a1SLionel Sambuc/// \param other The other object to compare this one to.
141*11be35a1SLionel Sambuc///
142*11be35a1SLionel Sambuc/// \return True if this object and other are equal; false otherwise.
143*11be35a1SLionel Sambuctemplate< class T >
144*11be35a1SLionel Sambucbool
145*11be35a1SLionel Sambucutils::optional< T >::operator==(const optional< T >& other) const
146*11be35a1SLionel Sambuc{
147*11be35a1SLionel Sambuc    if (_data == NULL && other._data == NULL) {
148*11be35a1SLionel Sambuc        return true;
149*11be35a1SLionel Sambuc    } else if (_data == NULL || other._data == NULL) {
150*11be35a1SLionel Sambuc        return false;
151*11be35a1SLionel Sambuc    } else {
152*11be35a1SLionel Sambuc        INV(_data != NULL && other._data != NULL);
153*11be35a1SLionel Sambuc        return *_data == *other._data;
154*11be35a1SLionel Sambuc    }
155*11be35a1SLionel Sambuc}
156*11be35a1SLionel Sambuc
157*11be35a1SLionel Sambuc
158*11be35a1SLionel Sambuc/// Inequality comparator.
159*11be35a1SLionel Sambuc///
160*11be35a1SLionel Sambuc/// \param other The other object to compare this one to.
161*11be35a1SLionel Sambuc///
162*11be35a1SLionel Sambuc/// \return True if this object and other are different; false otherwise.
163*11be35a1SLionel Sambuctemplate< class T >
164*11be35a1SLionel Sambucbool
165*11be35a1SLionel Sambucutils::optional< T >::operator!=(const optional< T >& other) const
166*11be35a1SLionel Sambuc{
167*11be35a1SLionel Sambuc    return !(*this == other);
168*11be35a1SLionel Sambuc}
169*11be35a1SLionel Sambuc
170*11be35a1SLionel Sambuc
171*11be35a1SLionel Sambuc/// Gets the value hold by the optional object.
172*11be35a1SLionel Sambuc///
173*11be35a1SLionel Sambuc/// \pre The optional object must not be none.
174*11be35a1SLionel Sambuc///
175*11be35a1SLionel Sambuc/// \return A reference to the data.
176*11be35a1SLionel Sambuctemplate< class T >
177*11be35a1SLionel Sambucconst T&
178*11be35a1SLionel Sambucutils::optional< T >::get(void) const
179*11be35a1SLionel Sambuc{
180*11be35a1SLionel Sambuc    PRE(_data != NULL);
181*11be35a1SLionel Sambuc    return *_data;
182*11be35a1SLionel Sambuc}
183*11be35a1SLionel Sambuc
184*11be35a1SLionel Sambuc
185*11be35a1SLionel Sambuc/// Gets the value of this object with a default fallback.
186*11be35a1SLionel Sambuc///
187*11be35a1SLionel Sambuc/// \param default_value The value to return if this object holds no value.
188*11be35a1SLionel Sambuc///
189*11be35a1SLionel Sambuc/// \return A reference to the data in the optional object, or the reference
190*11be35a1SLionel Sambuc/// passed in as a parameter.
191*11be35a1SLionel Sambuctemplate< class T >
192*11be35a1SLionel Sambucconst T&
193*11be35a1SLionel Sambucutils::optional< T >::get_default(const T& default_value) const
194*11be35a1SLionel Sambuc{
195*11be35a1SLionel Sambuc    if (_data != NULL)
196*11be35a1SLionel Sambuc        return *_data;
197*11be35a1SLionel Sambuc    else
198*11be35a1SLionel Sambuc        return default_value;
199*11be35a1SLionel Sambuc}
200*11be35a1SLionel Sambuc
201*11be35a1SLionel Sambuc
202*11be35a1SLionel Sambuc/// Tests whether the optional object contains data or not.
203*11be35a1SLionel Sambuc///
204*11be35a1SLionel Sambuc/// \return True if the object is not none; false otherwise.
205*11be35a1SLionel Sambuctemplate< class T >
206*11be35a1SLionel Sambucutils::optional< T >::operator bool(void) const
207*11be35a1SLionel Sambuc{
208*11be35a1SLionel Sambuc    return _data != NULL;
209*11be35a1SLionel Sambuc}
210*11be35a1SLionel Sambuc
211*11be35a1SLionel Sambuc
212*11be35a1SLionel Sambuc/// Tests whether the optional object contains data or not.
213*11be35a1SLionel Sambuc///
214*11be35a1SLionel Sambuc/// \return True if the object is not none; false otherwise.
215*11be35a1SLionel Sambuctemplate< class T >
216*11be35a1SLionel SambucT&
217*11be35a1SLionel Sambucutils::optional< T >::get(void)
218*11be35a1SLionel Sambuc{
219*11be35a1SLionel Sambuc    PRE(_data != NULL);
220*11be35a1SLionel Sambuc    return *_data;
221*11be35a1SLionel Sambuc}
222*11be35a1SLionel Sambuc
223*11be35a1SLionel Sambuc
224*11be35a1SLionel Sambuc/// Injects the object into a stream.
225*11be35a1SLionel Sambuc///
226*11be35a1SLionel Sambuc/// \param output The stream into which to inject the object.
227*11be35a1SLionel Sambuc/// \param object The object to format.
228*11be35a1SLionel Sambuc///
229*11be35a1SLionel Sambuc/// \return The output stream.
230*11be35a1SLionel Sambuctemplate< class T >
231*11be35a1SLionel Sambucstd::ostream& utils::operator<<(std::ostream& output,
232*11be35a1SLionel Sambuc                                const optional< T >& object)
233*11be35a1SLionel Sambuc{
234*11be35a1SLionel Sambuc    if (!object) {
235*11be35a1SLionel Sambuc        output << "none";
236*11be35a1SLionel Sambuc    } else {
237*11be35a1SLionel Sambuc        output << object.get();
238*11be35a1SLionel Sambuc    }
239*11be35a1SLionel Sambuc    return output;
240*11be35a1SLionel Sambuc}
241*11be35a1SLionel Sambuc
242*11be35a1SLionel Sambuc
243*11be35a1SLionel Sambuc/// Helper function to instantiate optional objects.
244*11be35a1SLionel Sambuc///
245*11be35a1SLionel Sambuc/// \param value The value for the optional object.  Shouldn't be none, as
246*11be35a1SLionel Sambuc///     optional objects can be constructed from none right away.
247*11be35a1SLionel Sambuc///
248*11be35a1SLionel Sambuc/// \return A new optional object.
249*11be35a1SLionel Sambuctemplate< class T >
250*11be35a1SLionel Sambucutils::optional< T >
251*11be35a1SLionel Sambucutils::make_optional(const T& value)
252*11be35a1SLionel Sambuc{
253*11be35a1SLionel Sambuc    return optional< T >(value);
254*11be35a1SLionel Sambuc}
255*11be35a1SLionel Sambuc
256*11be35a1SLionel Sambuc
257*11be35a1SLionel Sambuc#endif  // !defined(UTILS_OPTIONAL_IPP)
258