0a0736c4457658a50a34181d5145fcf1b40cc333
[platform/framework/web/wrt-commons.git] / modules / core / include / dpl / optional.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /*
17  * @file        optional_value.h
18  * @author      Lukasz Wrzosek (l.wrzosek@samsung.com)
19  * @version     1.0
20  */
21
22 #ifndef DPL_OPTIONAL_H
23 #define DPL_OPTIONAL_H
24
25 #include <dpl/exception.h>
26
27 namespace DPL
28 {
29
30 template <typename Type>
31 class Optional
32 {
33     class Exception
34     {
35     public:
36         DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
37         DECLARE_EXCEPTION_TYPE(Base, NullReference)
38     };
39
40 public:
41     Optional() :
42         m_null(true),
43         m_value()
44     {
45     }
46
47     Optional(const Type& t) :
48         m_null(false),
49         m_value(t)
50     {
51     }
52
53     bool IsNull() const
54     {
55         return m_null;
56     }
57
58     Type& operator*()
59     {
60         if (m_null) Throw(typename Exception::NullReference);
61         return m_value;
62     }
63
64     const Type& operator*() const
65     {
66         if (m_null) Throw(typename Exception::NullReference);
67         return m_value;
68     }
69
70     const Type* operator->() const
71     {
72         if (m_null) Throw(typename Exception::NullReference);
73         return &m_value;
74     }
75
76     Type* operator->()
77     {
78         if (m_null) Throw(typename Exception::NullReference);
79         return &m_value;
80     }
81
82     bool operator!() const
83     {
84         return m_null;
85     }
86
87     Optional<Type>& operator=(const Type& other)
88     {
89         m_null = false;
90         m_value = other;
91         return *this;
92     }
93
94     bool operator==(const Optional<Type>& aSecond) const
95     {
96         return LogicalOperator<true>(*this, aSecond, std::equal_to<Type>(), std::equal_to<bool>());
97     }
98
99     bool operator==(const Type& aSecond) const
100     {
101         return Optional<Type>(aSecond) == *this;
102     }
103
104     bool operator!=(const Optional<Type>& aSecond) const
105     {
106         return !(*this == aSecond);
107     }
108
109     bool operator<(const Optional<Type>& aSecond) const
110     {
111         return LogicalOperator<false>(*this, aSecond, std::less<Type>(), std::less<bool>());
112     }
113
114     bool operator>(const Optional<Type>& aSecond) const
115     {
116         return LogicalOperator<false>(*this, aSecond, std::greater<Type>(), std::greater<bool>());
117     }
118
119     bool operator<=(const Optional<Type>& aSecond) const
120     {
121         return *this == aSecond || *this < aSecond;
122     }
123
124     bool operator>=(const Optional<Type>& aSecond) const
125     {
126         return *this == aSecond || *this > aSecond;
127     }
128
129     static Optional<Type> Null;
130
131 private:
132     bool m_null;
133     Type m_value;
134
135     template <bool taEquality, typename taComparator, typename taNullComparator>
136     static bool LogicalOperator(const Optional<Type>& aFirst, const Optional<Type>& aSecond,
137                                 taComparator aComparator, taNullComparator aNullComparator)
138     {
139         if (aFirst.m_null == aSecond.m_null)
140         {
141             if (aFirst.m_null)
142             {
143                 return taEquality;
144             }
145             else
146             {
147                 return  aComparator(aFirst.m_value, aSecond.m_value);
148             }
149         }
150         else
151         {
152             return aNullComparator(aFirst.m_null, aSecond.m_null);
153         }
154     }
155 };
156
157 template<typename Type>
158 Optional<Type> Optional<Type>::Null = Optional<Type>();
159
160 } //namespace DPL
161
162 template<typename Type>
163 std::ostream& operator<<(std::ostream& aStream, const DPL::Optional<Type>& aOptional)
164 {
165     if (aOptional.IsNull())
166     {
167         return aStream << "null optional";
168     }
169     else
170     {
171         return aStream << *aOptional;
172     }
173 }
174
175 #endif // DPL_OPTIONAL_VALUE_H