• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2019-2022 Google, Inc.
5 
6 /// @file
7 
8 #ifndef __ABG_CXX_COMPAT_H
9 #define __ABG_CXX_COMPAT_H
10 
11 // C++17 support (via custom implementations if compiled with earlier standard)
12 
13 #if __cplusplus >= 201703L
14 
15 #include <optional>
16 
17 #else
18 
19 #include <stdexcept> // for throwing std::runtime_error("bad_optional_access")
20 
21 #endif
22 
23 namespace abg_compat {
24 
25 #if __cplusplus >= 201703L
26 
27 using std::optional;
28 
29 #else
30 
31 // <optional>
32 
33 /// Simplified implementation of std::optional just enough to be used as a
34 /// replacement for our purposes and when compiling with pre C++17.
35 ///
36 /// The implementation intentionally does not support a whole lot of features
37 /// to minimize the maintenance effort with this.
38 template <typename T> class optional
39 {
40   bool has_value_;
41   T    value_;
42 
43 public:
44   optional() : has_value_(false), value_() {}
45   optional(const T& value) : has_value_(true), value_(value) {}
46 
47   bool
48   has_value() const noexcept
49   {
50     return has_value_;
51   }
52 
53   const T&
54   value() const
55   {
56     if (!has_value_)
57       throw std::runtime_error("bad_optional_access");
58     return value_;
59   }
60 
61   const T
62   value_or(const T& default_value) const
63   {
64     if (!has_value_)
65       return default_value;
66     return value_;
67   }
68 
69   const T&
70   operator*() const& noexcept
71   { return value_; }
72 
73   T&
74   operator*() & noexcept
75   { return value_; }
76 
77   const T*
78   operator->() const noexcept
79   { return &value_; }
80 
81   T*
82   operator->() noexcept
83   { return &value_; }
84 
85   optional&
86   operator=(const T& value)
87   {
88     has_value_ = true;
89     value_ = value;
90     return *this;
91   }
92 
93   explicit operator bool() const noexcept { return has_value(); }
94 };
95 
96 template <typename T, typename U>
97 bool
98 operator==(const optional<T>& lhs, const optional<U>& rhs)
99 {
100   if (!lhs.has_value() && !rhs.has_value())
101     return true;
102   if (!lhs.has_value() || !rhs.has_value())
103     return false;
104   return lhs.value() == rhs.value();
105 }
106 
107 template <typename T, typename U>
108 bool
109 operator!=(const optional<T>& lhs, const optional<U>& rhs)
110 {
111   return !(lhs == rhs);
112 }
113 
114 #endif
115 }
116 
117 #endif  // __ABG_CXX_COMPAT_H
118