1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
5 * Copyright 2019 Samsung Electronics Co., Ltd
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
23 #include <type_traits>
27 * Minimalistic implementation of standard library std::optional (c++17) for c++11 compiler.
29 * After project conversion to C++17 standard, this template class will be deleted and
30 * Optional will point to std::optional.
32 * Allowed operations (note, to make code simplier, than original, value class must have accessible copy and move constructor):
33 * - constructing empty (valueless) object
34 * - copying Optional (with and without value)
35 * - moving Optional (with and without value)
36 * - querying, if Optional has value (via explicit operator bool), for example:
37 * Optional<int> v = ...;
38 * if (v) ... // if v has value, then do something
39 * - accessing value (via operator *), for example:
40 * Optional<int> v = ...;
41 * auto z = *v; // z now has the same int, as v (copied)
42 * auto &y = *v; // y now has REFERENCE to int inside v, so modifying y modifies v
45 template < typename A >
53 bool hasValue = false;
58 * @brief Empty constructor.
59 * Creates empty Optional object, which will be false in boolean context.
63 * if (o) printf("1\n");
70 * @brief Single element constructor, when implicit convertion can be applied.
72 * This constructor will be selected, when type of given argument (U) is
73 * implicitly convertable to expected type A. In other words following
81 * @param a value held by Optional object will be initialized from a.
83 template < typename U = A, typename std::enable_if<
84 std::is_convertible< U&&, A >::value &&
85 std::is_constructible< A, U&& >::value &&
86 !std::is_same< typename std::decay< U >::type, Optional< A > >::value,
87 int* >::type = nullptr >
88 constexpr Optional( U&& a )
89 : place( std::forward< U >( a ) ), hasValue( true )
94 * @brief Single element constructor, when only explicit convertion can be applied.
96 * This constructor will be selected, when type of given argument (U) is
97 * convertable to expected type A.
99 * @param a value held by Optional object will be initialized from a.
101 template < typename U = A, typename std::enable_if<
102 !std::is_convertible< U&&, A >::value &&
103 std::is_constructible< A, U&& >::value &&
104 !std::is_same< typename std::decay< U >::type, Optional< A > >::value,
105 int* >::type = nullptr >
106 explicit constexpr Optional( U&& a )
107 : place( std::forward< U >( a ) ), hasValue( true )
112 * @brief Copy constructor.
114 * @param v Optional value to copy from. Will cause to copy data held by object v,
117 Optional( const Optional& v ) : hasValue( v.hasValue )
120 new( &place ) A( v.place );
124 * @brief Move constructor.
126 * @param v Optional value to copy from. Will move data help by v, if any.
127 * After construction \code{.cpp} bool(v) \endcode will be false.
129 Optional( Optional&& v ) : hasValue( v.hasValue )
132 new( &place ) A( std::move( v.place ) );
147 * @brief Explicit bool operator
149 * Will return true if and only if object is helding data.
151 explicit operator bool() const
157 * @brief Accessor (*) operator
159 * Will return modifiable reference to held object. Will assert, if not object is held.
168 * @brief Accessor (*) const operator
170 * Will return const reference to held object. Will assert, if not object is held.
172 const A& operator*() const
179 * @brief Accessor (->) operator
181 * Will return pointer to held object allowing access to the value's members.
182 * Will assert, if not object is held.
191 * @brief Accessor (->) operator
193 * Will return pointer to (const) held object allowing access to the value's members.
194 * Will assert, if not object is held.
196 const A* operator->() const
203 * @brief Assignment operator
205 * Will copy held value from v, if any.
207 * @param v Value to copy from
209 Optional& operator=( const Optional& v )
213 if( hasValue != v.hasValue )
216 new( &place ) A( v.place );
219 hasValue = v.hasValue;
230 * @brief Assignment move operator
232 * Will move held value from v, if any. In all cases v won't held a value
233 * after assignment is done.
235 * @param v Value to copy from
237 Optional& operator=( Optional&& v )
241 if( hasValue != v.hasValue )
244 new( &place ) A( std::move( v.place ) );
247 hasValue = v.hasValue;
251 place = std::move( v.place );
258 * @brief Assignment operator from value of type held.
260 * Will initialize held value from given parameter a.
261 * Type of the parameter must be the same (barring cv convertions),
262 * as the type of the value held.
264 * @param a Value to copy from
266 template < class U, class = typename std::enable_if<
267 std::is_same< typename std::remove_reference< U >::type, A >::value &&
268 std::is_constructible< A, U >::value &&
269 std::is_assignable< A&, U >::value >::type >
270 Optional& operator=( U&& a )
273 place = std::forward< U >( a );
277 new( &place ) A( std::forward< U >( a ) );
283 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H