libabigail
abg-cxx-compat.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2019-2023 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
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...