WRApplication
External kratos "application" for multiscale time integration.
OptionalRef.hpp
Go to the documentation of this file.
1 
3 // --- Core Includes ---
4 #include "includes/kratos_export_api.h" // KRATOS_API
5 #include "includes/exception.h" // KRATOS_ERROR
6 
7 // --- STL Includes ---
8 #include <type_traits> // alignment_of
9 #include <bitset> // bitset
10 #include <cstdint> // uintptr_t
11 
12 
13 namespace Kratos::WRApp {
14 
15 
21 template <class TElement>
23 {
24 private:
25  using PointerInteger = std::uintptr_t;
26 
27 public:
28  using value_type = TElement&;
29 
31  OptionalRef() noexcept
32  {
33  // First of all, make sure that the pointer doesn't use the least significant bit
34  static_assert(1 < std::alignment_of<TElement>(),
35  "OptionalReference cannot be used with types of size 1");
36 
37  // Assume that the size of PointerInteger is equal to the system's pointer size
38  static_assert(sizeof(PointerInteger) == sizeof(TElement*));
39 
40  // Verify that the alignment is identical to a pointer
41  static_assert(std::alignment_of<OptionalRef>() == std::alignment_of<TElement*>());
42 
43  mpElement.pointer = 0;
44  }
45 
47  explicit OptionalRef(TElement& rElement) noexcept
48  {
49  PointerInteger p = reinterpret_cast<PointerInteger>(&rElement);
50  mpElement.integer = p | static_cast<PointerInteger>(1);
51  }
52 
53  OptionalRef(OptionalRef&& rRhs) noexcept = default;
54 
55  OptionalRef(const OptionalRef& rRhs) noexcept = default;
56 
57  OptionalRef& operator=(OptionalRef&& rRhs) noexcept = default;
58 
59  OptionalRef& operator=(const OptionalRef& rRhs) noexcept = default;
60 
62  OptionalRef& operator=(TElement& rElement) noexcept
63  {
64  PointerInteger p = reinterpret_cast<PointerInteger>(&rElement);
65  mpElement.integer = p | static_cast<PointerInteger>(1);
66  }
67 
69  bool has_value() const noexcept
70  {
71  return mpElement.integer & static_cast<PointerInteger>(1);
72  }
73 
75  explicit operator bool () const noexcept
76  {
77  return this->has_value();
78  }
79 
82  TElement& value() const
83  {
84  if (!this->has_value()){
85  KRATOS_ERROR << "bad optional access";
86  } else {
87  PointerInteger p = mpElement.integer & ~static_cast<PointerInteger>(1);
88  return *reinterpret_cast<TElement*>(p);
89  }
90  }
91 
94  TElement& operator*() const noexcept
95  {
96  return this->value();
97  }
98 
100  void reset() noexcept
101  {
102  mpElement.integer = 0;
103  }
104 
105 private:
106  union {
107  TElement* pointer;
108  PointerInteger integer;
109  } mpElement;
110 }; // class OptionalRef
111 
112 
113 } // namespace Kratos::WRAp
An optional, modeling a pointer.
Definition: OptionalRef.hpp:23
void reset() noexcept
Clear the optional.
Definition: OptionalRef.hpp:100
OptionalRef(OptionalRef &&rRhs) noexcept=default
OptionalRef(const OptionalRef &rRhs) noexcept=default
TElement * pointer
Definition: OptionalRef.hpp:107
OptionalRef & operator=(TElement &rElement) noexcept
Assign the provided instance to the optional.
Definition: OptionalRef.hpp:62
TElement & value_type
Definition: OptionalRef.hpp:28
bool has_value() const noexcept
Check whether the optional is valid.
Definition: OptionalRef.hpp:69
OptionalRef & operator=(const OptionalRef &rRhs) noexcept=default
TElement & value() const
Access the stored reference.
Definition: OptionalRef.hpp:82
OptionalRef() noexcept
Construct an invalid (uninitialized) optional.
Definition: OptionalRef.hpp:31
TElement & operator*() const noexcept
Access the stored reference.
Definition: OptionalRef.hpp:94
OptionalRef(TElement &rElement) noexcept
Construct an optional reference to the provided instance.
Definition: OptionalRef.hpp:47
PointerInteger integer
Definition: OptionalRef.hpp:108
OptionalRef & operator=(OptionalRef &&rRhs) noexcept=default
Definition: MPIUtils.hpp:9