Lens AI Profiler Cpp
optional.hpp
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #ifndef _OPTIONAL_HPP_
21 #define _OPTIONAL_HPP_
22 
23 // This is a simplistic substitute for std::optional until we require C++17
24 
25 #if (__cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L))
26 #include <optional>
27 using std::optional;
28 #else
29 
30 #include <type_traits>
31 
32 namespace datasketches {
33 
34 template<typename T>
35 class optional {
36 public:
37 
38  optional() noexcept: initialized_(false) {}
39 
40  optional(const T& value) noexcept(std::is_nothrow_copy_constructible<T>::value) {
41  new (&value_) T(value);
42  initialized_ = true;
43  }
44 
45  optional(T&& value) noexcept(std::is_nothrow_move_constructible<T>::value) {
46  new (&value_) T(std::move(value));
47  initialized_ = true;
48  }
49 
50  // conversion from compatible types
51  template<typename TT>
52  optional(const optional<TT>& other) noexcept(std::is_nothrow_constructible<T, TT>::value): initialized_(false) {
53  if (other.initialized_) {
54  new (&value_) T(other.value_);
55  initialized_ = true;
56  }
57  }
58 
59  optional(const optional& other) noexcept(std::is_nothrow_copy_constructible<T>::value): initialized_(false) {
60  if (other.initialized_) {
61  new (&value_) T(other.value_);
62  initialized_ = true;
63  }
64  }
65 
66  optional(optional&& other) noexcept(std::is_nothrow_move_constructible<T>::value): initialized_(false) {
67  if (other.initialized_) {
68  new (&value_) T(std::move(other.value_));
69  initialized_ = true;
70  }
71  }
72 
73  ~optional() noexcept(std::is_nothrow_destructible<T>::value) {
74  if (initialized_) value_.~T();
75  }
76 
77  explicit operator bool() const noexcept {
78  return initialized_;
79  }
80 
81  optional& operator=(const optional& other)
82  noexcept(std::is_nothrow_copy_constructible<T>::value && std::is_nothrow_copy_assignable<T>::value) {
83  if (initialized_) {
84  if (other.initialized_) {
85  value_ = other.value_;
86  } else {
87  reset();
88  }
89  } else {
90  if (other.initialized_) {
91  new (&value_) T(other.value_);
92  initialized_ = true;
93  }
94  }
95  return *this;
96  }
97 
98  optional& operator=(optional&& other)
99  noexcept(std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value) {
100  if (initialized_) {
101  if (other.initialized_) {
102  value_ = std::move(other.value_);
103  } else {
104  reset();
105  }
106  } else {
107  if (other.initialized_) {
108  new (&value_) T(std::move(other.value_));
109  initialized_ = true;
110  }
111  }
112  return *this;
113  }
114 
115  template<typename... Args>
116  void emplace(Args&&... args) noexcept(std::is_nothrow_constructible<T, Args...>::value) {
117  new (&value_) T(args...);
118  initialized_ = true;
119  }
120 
121  T& operator*() & noexcept { return value_; }
122  const T& operator*() const & noexcept { return value_; }
123  T&& operator*() && noexcept { return std::move(value_); }
124  const T&& operator*() const && noexcept { return std::move(value_); }
125 
126  T* operator->() noexcept { return &value_; }
127  const T* operator->() const noexcept { return &value_; }
128 
129  void reset() noexcept(std::is_nothrow_destructible<T>::value) {
130  if (initialized_) value_.~T();
131  initialized_ = false;
132  }
133 
134 private:
135  union {
136  T value_;
137  };
138  bool initialized_;
139 
140  // for converting constructor
141  template<typename TT> friend class optional;
142 };
143 
144 } // namespace
145 
146 #endif // C++17
147 
148 #endif // _OPTIONAL_HPP_
Definition: optional.hpp:35
DataSketches namespace.
Definition: common_defs.hpp:32