FLANG

reference.h
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
Fortran::common::Reference
Definition: reference.h:18