Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Common/reference.h ------------------------*- C++ -*-===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // Implements a better std::reference_wrapper<> template class with |
10 | // move semantics, equality testing, and member access. |
11 | // Use Reference<A> in place of a real A& reference when assignability is |
12 | // required; safer than a bare pointer because it's guaranteed to not be null. |
13 | |
14 | #ifndef FORTRAN_COMMON_REFERENCE_H_ |
15 | #define FORTRAN_COMMON_REFERENCE_H_ |
16 | #include <type_traits> |
17 | namespace Fortran::common { |
18 | template <typename A> class Reference { |
19 | public: |
20 | using type = A; |
21 | Reference(type &x) : p_{&x} {} |
22 | Reference(const Reference &that) : p_{that.p_} {} |
23 | Reference(Reference &&that) : p_{that.p_} {} |
24 | Reference &operator=(const Reference &that) { |
25 | p_ = that.p_; |
26 | return *this; |
27 | } |
28 | Reference &operator=(Reference &&that) { |
29 | p_ = that.p_; |
30 | return *this; |
31 | } |
32 | |
33 | // Implicit conversions to references are supported only for |
34 | // const-qualified types in order to avoid any pernicious |
35 | // creation of a temporary copy in cases like: |
36 | // Reference<type> ref; |
37 | // const Type &x{ref}; // creates ref to temp copy! |
38 | operator std::conditional_t<std::is_const_v<type>, type &, void>() |
39 | const noexcept { |
40 | if constexpr (std::is_const_v<type>) { |
41 | return *p_; |
42 | } |
43 | } |
44 | |
45 | type &get() const noexcept { return *p_; } |
46 | type *operator->() const { return p_; } |
47 | type &operator*() const { return *p_; } |
48 | |
49 | bool operator==(std::add_const_t<A> &that) const { |
50 | return p_ == &that || *p_ == that; |
51 | } |
52 | bool operator!=(std::add_const_t<A> &that) const { return !(*this == that); } |
53 | bool operator==(const Reference &that) const { |
54 | return p_ == that.p_ || *this == *that.p_; |
55 | } |
56 | bool operator!=(const Reference &that) const { return !(*this == that); } |
57 | |
58 | private: |
59 | type *p_; // never null |
60 | }; |
61 | template <typename A> Reference(A &) -> Reference<A>; |
62 | } // namespace Fortran::common |
63 | #endif |
64 |
Warning: This file is not a C or C++ file. It does not have highlighting.