Low-Level Abstraction of Memory Access
ProxyRefOpMixin.hpp
Go to the documentation of this file.
1 // Copyright 2022 Bernhard Manfred Gruber
2 // SPDX-License-Identifier: MPL-2.0
3 
4 #pragma once
5 
6 #include "macros.hpp"
7 
8 namespace llama
9 {
12  template<typename Derived, typename ValueType>
14  {
15  private:
16  LLAMA_FN_HOST_ACC_INLINE constexpr auto derived() -> Derived&
17  {
18  return static_cast<Derived&>(*this);
19  }
20 
21  // in principle, load() could be const, but we use it only from non-const functions
22  LLAMA_FN_HOST_ACC_INLINE constexpr auto load() -> ValueType
23  {
24  return static_cast<ValueType>(derived());
25  }
26 
27  LLAMA_FN_HOST_ACC_INLINE constexpr void store(ValueType t)
28  {
29  derived() = std::move(t);
30  }
31 
32  public:
33  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator+=(const ValueType& rhs) -> Derived&
34  {
35  ValueType lhs = load();
36  lhs += rhs;
37  store(lhs);
38  return derived();
39  }
40 
41  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator-=(const ValueType& rhs) -> Derived&
42  {
43  ValueType lhs = load();
44  lhs -= rhs;
45  store(lhs);
46  return derived();
47  }
48 
49  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator*=(const ValueType& rhs) -> Derived&
50  {
51  ValueType lhs = load();
52  lhs *= rhs;
53  store(lhs);
54  return derived();
55  }
56 
57  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator/=(const ValueType& rhs) -> Derived&
58  {
59  ValueType lhs = load();
60  lhs /= rhs;
61  store(lhs);
62  return derived();
63  }
64 
65  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator%=(const ValueType& rhs) -> Derived&
66  {
67  ValueType lhs = load();
68  lhs %= rhs;
69  store(lhs);
70  return derived();
71  }
72 
73  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator<<=(const ValueType& rhs) -> Derived&
74  {
75  ValueType lhs = load();
76  lhs <<= rhs;
77  store(lhs);
78  return derived();
79  }
80 
81  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator>>=(const ValueType& rhs) -> Derived&
82  {
83  ValueType lhs = load();
84  lhs >>= rhs;
85  store(lhs);
86  return derived();
87  }
88 
89  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator&=(const ValueType& rhs) -> Derived&
90  {
91  ValueType lhs = load();
92  lhs &= rhs;
93  store(lhs);
94  return derived();
95  }
96 
97  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator|=(const ValueType& rhs) -> Derived&
98  {
99  ValueType lhs = load();
100  lhs |= rhs;
101  store(lhs);
102  return derived();
103  }
104 
105  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator^=(const ValueType& rhs) -> Derived&
106  {
107  ValueType lhs = load();
108  lhs ^= rhs;
109  store(lhs);
110  return derived();
111  }
112 
113  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator++() -> Derived&
114  {
115  ValueType v = load();
116  ++v;
117  store(v);
118  return derived();
119  }
120 
121  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator++(int) -> ValueType
122  {
123  ValueType v = load();
124  ValueType old = v++;
125  store(v);
126  return old;
127  }
128 
129  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator--() -> Derived&
130  {
131  ValueType v = load();
132  --v;
133  store(v);
134  return derived();
135  }
136 
137  LLAMA_FN_HOST_ACC_INLINE constexpr auto operator--(int) -> ValueType
138  {
139  ValueType v = load();
140  ValueType old = v--;
141  store(v);
142  return old;
143  }
144 
145  LLAMA_FN_HOST_ACC_INLINE friend constexpr void swap(Derived a, Derived b) noexcept
146  {
147  const auto va = static_cast<ValueType>(a);
148  const auto vb = static_cast<ValueType>(b);
149  a = vb;
150  b = va;
151  }
152  };
153 } // namespace llama
#define LLAMA_EXPORT
Definition: macros.hpp:192
#define LLAMA_FN_HOST_ACC_INLINE
Definition: macros.hpp:96
CRTP mixin for proxy reference types to support all compound assignment and increment/decrement opera...
constexpr auto operator++() -> Derived &
constexpr auto operator|=(const ValueType &rhs) -> Derived &
constexpr auto operator++(int) -> ValueType
constexpr auto operator<<=(const ValueType &rhs) -> Derived &
constexpr auto operator--(int) -> ValueType
constexpr auto operator*=(const ValueType &rhs) -> Derived &
constexpr auto operator>>=(const ValueType &rhs) -> Derived &
constexpr auto operator-=(const ValueType &rhs) -> Derived &
constexpr auto operator^=(const ValueType &rhs) -> Derived &
constexpr auto operator%=(const ValueType &rhs) -> Derived &
constexpr auto operator&=(const ValueType &rhs) -> Derived &
constexpr auto operator/=(const ValueType &rhs) -> Derived &
constexpr auto operator--() -> Derived &
constexpr friend void swap(Derived a, Derived b) noexcept
constexpr auto operator+=(const ValueType &rhs) -> Derived &