neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
i_optional.hpp
Go to the documentation of this file.
1// optional.hpp - v1.2.2
2/*
3 * Copyright (c) 2007 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39#include <optional>
40#include <stdexcept>
42
43namespace neolib
44{
45 template<typename T>
46 class i_optional;
47
48 template <typename T>
49 struct is_optional { static constexpr bool value = false; };
50 template <typename T>
51 struct is_optional<i_optional<T>> { static constexpr bool value = true; };
52
53 template <typename T>
55
56 template<typename T>
58 {
59 typedef i_optional<T> self_type;
60 // types
61 public:
62 typedef self_type abstract_type;
63 typedef T value_type;
65 typedef const value_type* const_pointer;
68 // state
69 public:
70 virtual bool has_value() const noexcept = 0;
71 virtual explicit operator bool() const noexcept = 0;
72 // element access
73 public:
74 virtual reference value() = 0;
75 virtual const_reference value() const = 0;
76 virtual const_reference value_or(const_reference aDefaultValue) const = 0;
77 virtual const_reference value_or(reference aDefaultValue) const = 0;
78 virtual reference value_or(reference aDefaultValue) = 0;
79 virtual reference operator*() = 0;
80 virtual const_reference operator*() const = 0;
81 virtual pointer operator->() = 0;
82 virtual const_pointer operator->() const = 0;
83 // modifiers
84 public:
85 virtual void reset() = 0;
86 virtual i_optional<T>& operator=(std::nullopt_t) noexcept = 0;
87 virtual i_optional<T>& operator=(const i_optional<T>& rhs) = 0;
88 virtual i_optional<T>& operator=(const T& value) = 0;
89 // comparison
90 public:
91 bool operator==(std::nullopt_t) const
92 {
93 return !has_value();
94 }
95 bool operator!=(std::nullopt_t) const
96 {
97 return has_value();
98 }
99 bool operator==(const i_optional<T>& that) const
100 {
101 if (has_value() != that.has_value())
102 return false;
103 if (!has_value())
104 return true;
105 return value() == that.value();
106 }
107 std::partial_ordering operator<=>(const i_optional<T>& that) const
108 {
109 if (has_value() < that.has_value())
110 return std::partial_ordering::less;
111 else if (has_value() > that.has_value())
112 return std::partial_ordering::greater;
113 else if (!has_value())
114 return std::partial_ordering::equivalent;
115 return value() <=> that.value();
116 }
117 };
118
119 template <typename T, typename U, typename = std::enable_if_t<!is_optional_v<U>, sfinae>>
120 inline bool operator==(const i_optional<T>& lhs, const U& rhs)
121 {
122 if (!lhs.has_value())
123 return false;
124 return lhs.get() == rhs;
125 }
126
127 template <typename T, typename U, typename = std::enable_if_t<!is_optional_v<U>, sfinae>>
128 inline bool operator==(const U& lhs, const i_optional<T>& rhs)
129 {
130 if (!rhs.has_value())
131 return false;
132 return lhs == rhs.get();
133 }
134
135 template <typename T, typename U, typename = std::enable_if_t<!is_optional_v<U>, sfinae>>
136 inline std::partial_ordering operator<=>(const i_optional<T>& lhs, const U& rhs)
137 {
138 if (!lhs.has_value())
139 return std::partial_ordering::less;
140 return lhs.get() <=> rhs;
141 }
142
143 template <typename T, typename U, typename = std::enable_if_t<!is_optional_v<U>, sfinae>>
144 inline std::partial_ordering operator<=>(const U& lhs, const i_optional<T>& rhs)
145 {
146 if (!rhs.has_value())
147 return std::partial_ordering::greater;
148 return lhs <=> rhs.get();
149 }
150}
value_type * pointer
value_type & reference
const value_type * const_pointer
bool operator!=(std::nullopt_t) const
std::partial_ordering operator<=>(const i_optional< T > &that) const
bool operator==(const i_optional< T > &that) const
virtual bool has_value() const noexcept=0
virtual void reset()=0
const value_type & const_reference
virtual const_reference value_or(const_reference aDefaultValue) const =0
virtual reference value()=0
self_type abstract_type
constexpr bool is_optional_v
std::partial_ordering operator<=>(const i_container< T, ConstIteratorType, IteratorType > &lhs, const i_container< T, ConstIteratorType, IteratorType > &rhs)
Definition plf_hive.h:79
static constexpr bool value