File Coverage

src/panda/optional.h
Criterion Covered Total %
statement 9 9 100.0
branch 5 6 83.3
condition n/a
subroutine n/a
pod n/a
total 14 15 93.3


line stmt bran cond sub pod time code
1             #pragma once
2              
3             #if __cpp_lib_optional >= 201603L
4             # include
5             namespace panda {
6             template
7             using optional = std::optional;
8             }
9             #else
10              
11             namespace panda {
12              
13             template struct optional {
14 72           ~optional() { reset(); }
15              
16 24           optional() : nullable_val(nullptr) {}
17            
18 24 50         optional(const T& val) : nullable_val(new (storage) T(val)) {}
19            
20             optional(const optional& oth) : nullable_val(oth ? new (storage) T(*oth) : nullptr) {}
21            
22             optional& operator=(optional const& oth) {
23             if (&oth != this) {
24             reset();
25             if (oth)
26             nullable_val = new (storage) T(*oth);
27             }
28             return *this;
29             }
30            
31             optional& operator=(const T& val) {
32             reset();
33             nullable_val = new (storage) T(val);
34             return *this;
35             }
36              
37 36           void reset() {
38 36 100         if (nullable_val)
39 12           nullable_val->~T();
40 36           nullable_val = nullptr;
41 36           }
42              
43             T& operator*() { return *nullable_val; }
44             const T& operator*() const { return *nullable_val; }
45             T* operator->() { return nullable_val; }
46             const T* operator->() const { return nullable_val; }
47              
48 64 100         T value_or(const T& default_val) const { return nullable_val ? *nullable_val : default_val; }
49              
50             T value() const { return *nullable_val; }
51              
52             explicit operator bool() const { return nullable_val != nullptr; }
53              
54             private:
55             T* nullable_val;
56             alignas(alignof(T)) char storage[sizeof(T)];
57             };
58              
59             template struct optional_tools {
60             using type = optional;
61             static type default_value () { return type{}; }
62             };
63              
64             template <> struct optional_tools {
65             using type = void;
66             static void default_value () {}
67             };
68              
69             template inline constexpr bool operator== (const optional& lhs, const optional& rhs) {
70             return (lhs && rhs) ? (*lhs == *rhs) : (lhs || rhs ? false : true);
71             }
72             template inline constexpr bool operator!= (const optional& lhs, const optional& rhs) { return !operator==(lhs, rhs); }
73              
74             template
75             inline constexpr bool operator< (const optional& lhs, const optional& rhs) {
76             return (lhs && rhs) ? (*lhs < *rhs) : (rhs ? true : false);
77             }
78              
79             template
80             constexpr bool operator<= (const optional& lhs, const optional& rhs) {
81             return (lhs && rhs) ? (*lhs < *rhs) : (lhs ? false : true);
82             }
83              
84             template
85             constexpr bool operator> (const optional& lhs, const optional& rhs) {
86             return (lhs && rhs) ? (*lhs < *rhs) : (lhs ? true : false);
87             }
88              
89             template
90             constexpr bool operator>= (const optional& lhs, const optional& rhs) {
91             return (lhs && rhs) ? (*lhs < *rhs) : (rhs ? false : true);
92             }
93              
94             template constexpr bool operator== (const optional& opt, const U& value) { return opt && *opt == value; }
95             template constexpr bool operator== (const T& value, const optional& opt) { return opt && value == *opt; }
96             template constexpr bool operator!= (const optional& opt, const U& value) { return !operator==(opt, value); }
97             template constexpr bool operator!= (const T& value, const optional& opt) { return !operator==(value, opt); }
98             template constexpr bool operator< (const optional& opt, const U& value) { return opt ? *opt < value : true; }
99             template constexpr bool operator< (const T& value, const optional& opt) { return opt && value < *opt; }
100             template constexpr bool operator<= (const optional& opt, const U& value) { return opt ? *opt <= value : true; }
101             template constexpr bool operator<= (const T& value, const optional& opt) { return opt && value <= *opt; }
102             template constexpr bool operator> (const optional& opt, const U& value) { return opt && *opt > value; }
103             template constexpr bool operator> (const T& value, const optional& opt) { return opt ? value > *opt : true; }
104             template constexpr bool operator>= (const optional& opt, const U& value) { return opt && *opt >= value; }
105             template constexpr bool operator>= (const T& value, const optional& opt) { return opt ? value >= *opt : true; }
106              
107             }
108              
109             #endif