aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/vm/Utility.hpp
blob: 189225e02fbdb296fbd5679297b35c0ee7aa4bf9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#pragma once

namespace OpenVic::Vm::utility {
   template<typename T>
   struct HandleBase {
      HandleBase(T* handle) : _handle(handle) {}

      T* handle() {
         return this->_handle;
      }

      const T* handle() const {
         return this->_handle;
      }

      operator T*() {
         return this->_handle;
      }

      operator const T*() const {
         return this->_handle;
      }

   protected:
      T* _handle;
   };

   template<typename Self, typename T>
   struct MoveOnlyHandleBase : HandleBase<T> {
      MoveOnlyHandleBase(Self&& other) : HandleBase<T>(other._handle) {
         other._handle = nullptr;
      }

      Self& operator=(Self&& other) {
         this->_handle = other._handle;
         other._handle = nullptr;
         return *this;
      }

      MoveOnlyHandleBase(Self const&) = delete;
      Self& operator=(Self const&) = delete;

   protected:
      using HandleBase<T>::HandleBase;
   };

   template<typename Self, typename Derived>
   struct MoveOnlyHandleDerived : Derived {
      using Derived::Derived;

      MoveOnlyHandleDerived(Self&& other) : Derived(other._handle) {
         other._handle = nullptr;
      }

      Self& operator=(Self&& other) {
         this->_handle = other._handle;
         other._handle = nullptr;
         return *this;
      }

      MoveOnlyHandleDerived(Self const&) = delete;
      Self& operator=(Self const&) = delete;

      Derived& as_ref() {
         return *this;
      }

      Derived const& as_ref() const {
         return *this;
      }
   };
}