File: unique-pointer.hpp

package info (click to toggle)
higan 098-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 11,904 kB
  • ctags: 13,286
  • sloc: cpp: 108,285; ansic: 778; makefile: 32; sh: 18
file content (102 lines) | stat: -rw-r--r-- 2,484 bytes parent folder | download | duplicates (2)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#pragma once

namespace nall {

template<typename T>
struct unique_pointer {
  using type = T;
  T* pointer = nullptr;
  function<auto (T*) -> void> deleter;

  unique_pointer(const unique_pointer&) = delete;
  auto operator=(const unique_pointer&) -> unique_pointer& = delete;

  unique_pointer(T* pointer = nullptr, const function<void (T*)>& deleter = {}) : pointer(pointer), deleter(deleter) {}
  ~unique_pointer() { reset(); }

  auto operator=(T* source) -> unique_pointer& {
    reset();
    pointer = source;
    return *this;
  }

  explicit operator bool() const { return pointer; }

  auto operator->() -> T* { return pointer; }
  auto operator->() const -> const T* { return pointer; }

  auto operator*() -> T& { return *pointer; }
  auto operator*() const -> const T& { return *pointer; }

  auto operator()() -> T& { return *pointer; }
  auto operator()() const -> const T& { return *pointer; }

  auto data() -> T* { return pointer; }
  auto data() const -> const T* { return pointer; }

  auto release() -> T* {
    auto result = pointer;
    pointer = nullptr;
    return result;
  }

  auto reset() -> void {
    if(pointer) {
      if(deleter) {
        deleter(pointer);
      } else {
        delete pointer;
      }
      pointer = nullptr;
    }
  }
};

template<typename T>
struct unique_pointer<T[]> {
  using type = T;
  T* pointer = nullptr;
  function<auto (T*) -> void> deleter;

  unique_pointer(const unique_pointer&) = delete;
  auto operator=(const unique_pointer&) -> unique_pointer& = delete;

  unique_pointer(T* pointer = nullptr, const function<void (T*)>& deleter = {}) : pointer(pointer), deleter(deleter) {}
  ~unique_pointer() { reset(); }

  auto operator=(T* source) -> unique_pointer& {
    reset();
    pointer = source;
    return *this;
  }

  explicit operator bool() const { return pointer; }

  auto operator()() -> T* { return pointer; }
  auto operator()() const -> T* { return pointer; }

  alwaysinline auto operator[](uint offset) -> T& { return pointer[offset]; }
  alwaysinline auto operator[](uint offset) const -> const T& { return pointer[offset]; }

  auto data() -> T* { return pointer; }
  auto data() const -> const T* { return pointer; }

  auto release() -> T* {
    auto result = pointer;
    pointer = nullptr;
    return result;
  }

  auto reset() -> void {
    if(pointer) {
      if(deleter) {
        deleter(pointer);
      } else {
        delete[] pointer;
      }
      pointer = nullptr;
    }
  }
};

}