1//
2// Optional.h
3//
4// Library: Foundation
5// Package: Core
6// Module: Optional
7//
8// Definition of the Optional class template.
9//
10// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_Optional_INCLUDED
18#define Foundation_Optional_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/Exception.h"
23#include <algorithm>
24
25
26namespace Poco {
27
28
29template <typename C>
30class Optional
31 /// Optional is a simple wrapper class for value types
32 /// that allows to introduce a specified/unspecified state
33 /// to value objects.
34 ///
35 /// An Optional can be default constructed. In this case,
36 /// the Optional will have a Null value and isSpecified() will
37 /// return false. Calling value()(without default value) on
38 /// a Null object will throw a NullValueException.
39 ///
40 /// An Optional can also be constructed from a value.
41 /// It is possible to assign a value to an Optional, and
42 /// to reset an Optional to contain a Null value by calling
43 /// clear().
44 ///
45 /// For use with Optional, the value type should support
46 /// default construction.
47 ///
48 /// Note that the Optional class is basically the same as
49 /// Nullable. However, serializers may treat Nullable
50 /// and Optional differently. An example is XML serialization based
51 /// on XML Schema, where Optional would be used for an element with
52 /// minOccurs == 0, whereas Nullable would be used on an element with
53 /// nillable == true.
54{
55public:
56 Optional():
57 /// Creates an empty Optional.
58 _value(),
59 _isSpecified(false)
60 {
61 }
62
63 Optional(const C& value):
64 /// Creates a Optional with the given value.
65 _value(value),
66 _isSpecified(true)
67 {
68 }
69
70 Optional(const Optional& other):
71 /// Creates a Optional by copying another one.
72 _value(other._value),
73 _isSpecified(other._isSpecified)
74 {
75 }
76
77 ~Optional()
78 /// Destroys the Optional.
79 {
80 }
81
82 Optional& assign(const C& value)
83 /// Assigns a value to the Optional.
84 {
85 _value = value;
86 _isSpecified = true;
87 return *this;
88 }
89
90 Optional& assign(const Optional& other)
91 /// Assigns another Optional.
92 {
93 Optional tmp(other);
94 swap(tmp);
95 return *this;
96 }
97
98 Optional& operator = (const C& value)
99 {
100 return assign(value);
101 }
102
103 Optional& operator = (const Optional& other)
104 {
105 return assign(other);
106 }
107
108 void swap(Optional& other)
109 {
110 std::swap(_value, other._value);
111 std::swap(_isSpecified, other._isSpecified);
112 }
113
114 const C& value() const
115 /// Returns the Optional's value.
116 ///
117 /// Throws a Poco::NullValueException if the value has not been specified.
118 {
119 if (_isSpecified)
120 return _value;
121 else
122 throw Poco::NullValueException();
123 }
124
125 const C& value(const C& deflt) const
126 /// Returns the Optional's value, or the
127 /// given default value if the Optional's
128 /// value has not been specified.
129 {
130 return _isSpecified ? _value : deflt;
131 }
132
133 bool isSpecified() const
134 /// Returns true iff the Optional's value has been specified.
135 {
136 return _isSpecified;
137 }
138
139 void clear()
140 /// Clears the Optional.
141 {
142 _isSpecified = false;
143 }
144
145private:
146 C _value;
147 bool _isSpecified;
148};
149
150
151template <typename C>
152inline void swap(Optional<C>& n1, Optional<C>& n2)
153{
154 n1.swap(n2);
155}
156
157
158} // namespace Poco
159
160
161#endif // Foundation_Optional_INCLUDED
162