1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2019-2020 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
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
71   { return value_; }
72 
73   T&
74   operator*()
75   { return value_; }
76 
77   const T*
78   operator->() const
79   { return &value_; }
80 
81   T*
82   operator->()
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 { return has_value_; }
94 };
95 
96 #endif
97 }
98 
99 #endif  // __ABG_CXX_COMPAT_H
100