Revert "[Tizen](ATSPI) Fix Native TC fails"
[platform/core/uifw/dali-adaptor.git] / dali / internal / accessibility / bridge / optional.h
1 #ifndef DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
2 #define DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H
3
4 /*
5  * Copyright 2019  Samsung Electronics Co., Ltd
6  *
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
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12
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.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <cassert>
22 #include <new>
23 #include <type_traits>
24 #include <utility>
25
26 /**
27  * Minimalistic implementation of standard library std::optional (c++17) for c++11 compiler.
28  *
29  * After project conversion to C++17 standard, this template class will be deleted and
30  * Optional will point to std::optional.
31  *
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
43  */
44
45 template < typename A >
46 class Optional
47 {
48   /// \cond
49   union
50   {
51     A place;
52   };
53   bool hasValue = false;
54   /// \endcond
55
56 public:
57   /**
58    * @brief Empty constructor.
59    * Creates empty Optional object, which will be false in boolean context.
60    * So:
61    *   \code{.cpp}
62    *   Optional<int> o;
63    *   if (o) printf("1\n");
64    *   \endcode
65    * won't print 1.
66    */
67   Optional() {}
68
69   /**
70    * @brief Single element constructor, when implicit convertion can be applied.
71    *
72    * This constructor will be selected, when type of given argument (U) is
73    * implicitly convertable to expected type A. In other words following
74    * code must be valid:
75    *   \code{.cpp}
76    *   A foo() {
77    *     return U();
78    *   }
79    *   \endcode
80    *
81    * @param a value held by Optional object will be initialized from a.
82    */
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 )
90   {
91   }
92
93   /**
94    * @brief Single element constructor, when only explicit convertion can be applied.
95    *
96    * This constructor will be selected, when type of given argument (U) is
97    * convertable to expected type A.
98    *
99    * @param a value held by Optional object will be initialized from a.
100    */
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 )
108   {
109   }
110
111   /**
112    * @brief Copy constructor.
113    *
114    * @param v Optional value to copy from. Will cause to copy data held by object v,
115    * if v has data.
116    */
117   Optional( const Optional& v ) : hasValue( v.hasValue )
118   {
119     if( hasValue )
120       new( &place ) A( v.place );
121   }
122
123   /**
124    * @brief Move constructor.
125    *
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.
128    */
129   Optional( Optional&& v ) : hasValue( v.hasValue )
130   {
131     if( hasValue )
132       new( &place ) A( std::move( v.place ) );
133   }
134
135   /**
136    * @brief Destructor.
137    */
138   ~Optional()
139   {
140     if( hasValue )
141     {
142       place.~A();
143     }
144   }
145
146   /**
147    * @brief Explicit bool operator
148    *
149    * Will return true if and only if object is helding data.
150    */
151   explicit operator bool() const
152   {
153     return hasValue;
154   }
155
156   /**
157    * @brief Accessor (*) operator
158    *
159    * Will return modifiable reference to held object. Will assert, if not object is held.
160    */
161   A& operator*()
162   {
163     assert( hasValue );
164     return place;
165   }
166
167   /**
168    * @brief Accessor (*) const operator
169    *
170    * Will return const reference to held object. Will assert, if not object is held.
171    */
172   const A& operator*() const
173   {
174     assert( hasValue );
175     return place;
176   }
177
178   /**
179    * @brief Accessor (->) operator
180    *
181    * Will return pointer to held object allowing access to the value's members.
182    * Will assert, if not object is held.
183    */
184   A* operator->()
185   {
186     assert( hasValue );
187     return &place;
188   }
189
190   /**
191    * @brief Accessor (->) operator
192    *
193    * Will return pointer to (const) held object allowing access to the value's members.
194    * Will assert, if not object is held.
195    */
196   const A* operator->() const
197   {
198     assert( hasValue );
199     return &place;
200   }
201
202   /**
203    * @brief Assignment operator
204    *
205    * Will copy held value from v, if any.
206    *
207    * @param v Value to copy from
208    */
209   Optional& operator=( const Optional& v )
210   {
211     if( this != &v )
212     {
213       if( hasValue != v.hasValue )
214       {
215         if( v.hasValue )
216           new( &place ) A( v.place );
217         else
218           place.~A();
219         hasValue = v.hasValue;
220       }
221       else if( hasValue )
222       {
223         place = v.place;
224       }
225     }
226     return *this;
227   }
228
229   /**
230    * @brief Assignment move operator
231    *
232    * Will move held value from v, if any. In all cases v won't held a value
233    * after assignment is done.
234    *
235    * @param v Value to copy from
236    */
237   Optional& operator=( Optional&& v )
238   {
239     if( this != &v )
240     {
241       if( hasValue != v.hasValue )
242       {
243         if( v.hasValue )
244           new( &place ) A( std::move( v.place ) );
245         else
246           place.~A();
247         hasValue = v.hasValue;
248       }
249       else if( hasValue )
250       {
251         place = std::move( v.place );
252       }
253     }
254     return *this;
255   }
256
257   /**
258    * @brief Assignment operator from value of type held.
259    *
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.
263    *
264    * @param a Value to copy from
265    */
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 )
271   {
272     if( hasValue )
273       place = std::forward< U >( a );
274     else
275     {
276       hasValue = true;
277       new( &place ) A( std::forward< U >( a ) );
278     }
279     return *this;
280   }
281 };
282
283 #endif // DALI_INTERNAL_ACCESSIBILITY_BRIDGE_OPTIONAL_H