datasketches-cpp
Loading...
Searching...
No Matches
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>
27using std::optional;
28#else
29
30#include <type_traits>
31
32namespace datasketches {
33
34template<typename T>
35class optional {
36public:
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
134private:
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_
DataSketches namespace.
Definition binomial_bounds.hpp:38