1 #ifndef DALI_INTERNAL_ATSPI_ACCESSIBILITY_OPTIONAL_H
2 #define DALI_INTERNAL_ATSPI_ACCESSIBILITY_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 >
52 bool hasValue = false;
56 * @brief Empty constructor.
57 * Creates empty Optional object, which will be false in boolean context.
61 * if (o) printf("1\n");
68 * @brief Single element constructor, when implicit convertion can be applied.
69 * This constructor will be selected, when type of given argument (U) is
70 * implicitly convertable to expected type A. In other words following
77 * @param a value held by Optional object will be initialized from a.
79 template < typename U = A, typename std::enable_if<
80 std::is_convertible< U&&, A >::value &&
81 std::is_constructible< A, U&& >::value &&
82 !std::is_same< typename std::decay< U >::type, Optional< A > >::value,
83 int* >::type = nullptr >
84 constexpr Optional( U&& a )
85 : place( std::forward< U >( a ) ),
91 * @brief Single element constructor, when only explicit convertion can be applied.
92 * This constructor will be selected, when type of given argument (U) is
93 * convertable to expected type A.
94 * @param a value held by Optional object will be initialized from a.
96 template < typename U = A, typename std::enable_if<
97 !std::is_convertible< U&&, A >::value &&
98 std::is_constructible< A, U&& >::value &&
99 !std::is_same< typename std::decay< U >::type, Optional< A > >::value,
100 int* >::type = nullptr >
101 explicit constexpr Optional( U&& a )
102 : place( std::forward< U >( a ) ),
108 * @brief Copy constructor.
109 * @param v Optional value to copy from. Will cause to copy data held by object v,
112 Optional( const Optional& v ) : hasValue( v.hasValue )
116 new( &place ) A( v.place );
121 * @brief Move constructor.
122 * @param v Optional value to copy from. Will move data help by v, if any.
123 * After construction \code{.cpp} bool(v) \endcode will be false.
125 Optional( Optional&& v ) : hasValue( v.hasValue )
129 new( &place ) A( std::move( v.place ) );
145 * @brief Explicit bool operator
146 * Will return true if and only if object is helding data.
148 explicit operator bool() const
154 * @brief Accessor (*) operator
155 * Will return modifiable reference to held object. Will assert, if not object is held.
164 * @brief Accessor (*) const operator
165 * Will return const reference to held object. Will assert, if not object is held.
167 const A& operator*() const
174 * @brief Accessor (->) operator
175 * Will return pointer to held object allowing access to the value's members.
176 * Will assert, if not object is held.
185 * @brief Accessor (->) operator
186 * Will return pointer to (const) held object allowing access to the value's members.
187 * Will assert, if not object is held.
189 const A* operator->() const
196 * @brief Assignment operator
197 * Will copy held value from v, if any.
198 * @param v Value to copy from
200 Optional& operator=( const Optional& v )
204 if( hasValue != v.hasValue )
208 new( &place ) A( v.place );
214 hasValue = v.hasValue;
225 * @brief Assignment move operator
226 * Will move held value from v, if any. In all cases v won't held a value
227 * after assignment is done.
228 * @param v Value to copy from
230 Optional& operator=( Optional&& v )
234 if( hasValue != v.hasValue )
238 new( &place ) A( std::move( v.place ) );
244 hasValue = v.hasValue;
248 place = std::move( v.place );
255 * @brief Assignment operator from value of type held.
256 * Will initialize held value from given parameter a.
257 * Type of the parameter must be the same (barring cv convertions),
258 * as the type of the value held.
259 * @param a Value to copy from
261 template < class U, class = typename std::enable_if<
262 std::is_same< typename std::remove_reference< U >::type, A >::value &&
263 std::is_constructible< A, U >::value &&
264 std::is_assignable< A&, U >::value >::type >
265 Optional& operator=( U&& a )
269 place = std::forward< U >( a );
274 new( &place ) A( std::forward< U >( a ) );
280 #endif // DALI_INTERNAL_ATSPI_ACCESSIBILITY_OPTIONAL_H