Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / fluid / modules / gapi / include / opencv2 / gapi / util / optional.hpp
1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 //
5 // Copyright (C) 2018-2019 Intel Corporation
6
7
8 #ifndef OPENCV_GAPI_UTIL_OPTIONAL_HPP
9 #define OPENCV_GAPI_UTIL_OPTIONAL_HPP
10
11 #include "opencv2/gapi/util/variant.hpp"
12
13 // A poor man's `optional` implementation, incompletely modeled against C++17 spec.
14 namespace cv
15 {
16 namespace util
17 {
18     class bad_optional_access: public std::exception
19     {
20     public:
21         virtual const char *what() const noexcept override
22         {
23             return "Bad optional access";
24         }
25     };
26
27     // TODO: nullopt_t
28
29     // Interface ///////////////////////////////////////////////////////////////
30     template<typename T> class optional
31     {
32     public:
33         // Constructors
34         // NB.: there were issues with Clang 3.8 when =default() was used
35         // instead {}
36         optional() {};
37         optional(const optional&) = default;
38         explicit optional(T &&value) noexcept;
39         explicit optional(const T &value) noexcept;
40         optional(optional &&) noexcept;
41         // TODO: optional(nullopt_t) noexcept;
42         // TODO: optional(const optional<U> &)
43         // TODO: optional(optional<U> &&)
44         // TODO: optional(Args&&...)
45         // TODO: optional(initializer_list<U>)
46         // TODO: optional(U&& value);
47
48         // Assignment
49         optional& operator=(const optional& rhs) = default;
50         optional& operator=(optional&& rhs);
51
52         // Observers
53         T* operator-> ();
54         const T* operator-> () const;
55         T& operator* ();
56         const T& operator* () const;
57         // TODO: && versions
58
59         operator bool() const noexcept;
60         bool has_value() const noexcept;
61
62         T& value();
63         const T& value() const;
64         // TODO: && versions
65
66         template<class U>
67         T value_or(U &&default_value) const;
68
69         void swap(optional &other) noexcept;
70         void reset() noexcept;
71         // TODO: emplace
72
73         // TODO: operator==, !=, <, <=, >, >=
74
75     private:
76         struct nothing {};
77         util::variant<nothing, T> m_holder;
78     };
79
80     template<class T>
81     optional<typename std::decay<T>::type> make_optional(T&& value);
82
83     // TODO: Args... and initializer_list versions
84
85     // Implementation //////////////////////////////////////////////////////////
86     template<class T> optional<T>::optional(T &&v) noexcept
87         : m_holder(v)
88     {
89     }
90
91     template<class T> optional<T>::optional(const T &v) noexcept
92         : m_holder(v)
93     {
94     }
95
96     template<class T> optional<T>::optional(optional&& rhs) noexcept
97         : m_holder(std::move(rhs.m_holder))
98     {
99         rhs.reset();
100     }
101
102     template<class T> optional<T>& optional<T>::operator=(optional&& rhs)
103     {
104         m_holder = std::move(rhs.m_holder);
105         rhs.reset();
106         return *this;
107     }
108
109     template<class T> T* optional<T>::operator-> ()
110     {
111         return & *(*this);
112     }
113
114     template<class T> const T* optional<T>::operator-> () const
115     {
116         return & *(*this);
117     }
118
119     template<class T> T& optional<T>::operator* ()
120     {
121         return this->value();
122     }
123
124     template<class T> const T& optional<T>::operator* () const
125     {
126         return this->value();
127     }
128
129     template<class T> optional<T>::operator bool() const noexcept
130     {
131         return this->has_value();
132     }
133
134     template<class T> bool optional<T>::has_value() const noexcept
135     {
136         return util::holds_alternative<T>(m_holder);
137     }
138
139     template<class T> T& optional<T>::value()
140     {
141         if (!this->has_value())
142             throw_error(bad_optional_access());
143         return util::get<T>(m_holder);
144     }
145
146     template<class T> const T& optional<T>::value() const
147     {
148         if (!this->has_value())
149             throw_error(bad_optional_access());
150         return util::get<T>(m_holder);
151     }
152
153     template<class T>
154     template<class U> T optional<T>::value_or(U &&default_value) const
155     {
156         return (this->has_value() ? this->value() : T(default_value));
157     }
158
159     template<class T> void optional<T>::swap(optional<T> &other) noexcept
160     {
161         m_holder.swap(other.m_holder);
162     }
163
164     template<class T> void optional<T>::reset() noexcept
165     {
166         if (this->has_value())
167             m_holder = nothing{};
168     }
169
170     template<class T>
171     optional<typename std::decay<T>::type> make_optional(T&& value)
172     {
173         return optional<typename std::decay<T>::type>(std::forward<T>(value));
174     }
175 } // namespace util
176 } // namespace cv
177
178 #endif // OPENCV_GAPI_UTIL_OPTIONAL_HPP